diff options
Diffstat (limited to 'source')
223 files changed, 10698 insertions, 8810 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 55ade5fe5d9..46b533f33fd 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -526,7 +526,7 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb); typedef struct DMVertexAttribs { struct { struct MTFace *array; - int emOffset, glIndex; + int emOffset, glIndex, glTexco; } tface[MAX_MTFACE]; struct { @@ -541,7 +541,7 @@ typedef struct DMVertexAttribs { struct { float (*array)[3]; - int emOffset, glIndex; + int emOffset, glIndex, glTexco; } orco; int tottface, totmcol, tottang, totorco; diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 18f6ad21333..162b0de1d5a 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,17 +43,17 @@ extern "C" { /* these lines are grep'd, watch out for our not-so-awesome regex * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ -#define BLENDER_VERSION 258 -#define BLENDER_SUBVERSION 1 +#define BLENDER_VERSION 259 +#define BLENDER_SUBVERSION 0 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR a +#define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE beta +#define BLENDER_VERSION_CYCLE alpha struct ListBase; struct MemFile; diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 648e67cad8a..28950e4b2eb 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -101,6 +101,7 @@ typedef enum { typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin); typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin); +typedef void (*TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname); typedef struct ModifierTypeInfo { /* The user visible name for this modifier */ @@ -284,6 +285,16 @@ typedef struct ModifierTypeInfo { */ void (*foreachIDLink)(struct ModifierData *md, struct Object *ob, IDWalkFunc walk, void *userData); + + /* Should call the given walk function for each texture that the + * modifier data stores. This is used for finding all textures in + * the context for the UI. + * + * This function is optional. If it is not present, it will be + * assumed the modifier has no textures. + */ + void (*foreachTexLink)(struct ModifierData *md, struct Object *ob, + TexWalkFunc walk, void *userData); } ModifierTypeInfo; ModifierTypeInfo *modifierType_getInfo (ModifierType type); @@ -315,6 +326,10 @@ void modifiers_foreachObjectLink(struct Object *ob, void modifiers_foreachIDLink(struct Object *ob, IDWalkFunc walk, void *userData); +void modifiers_foreachTexLink(struct Object *ob, + TexWalkFunc walk, + void *userData); + struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type); struct ModifierData *modifiers_findByName(struct Object *ob, const char *name); void modifiers_clearErrors(struct Object *ob); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 0a96f8d74be..00cf03712ea 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1050,6 +1050,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, glEnd(); } } +#undef PASSATTRIB } static void emDM_drawFacesGLSL(DerivedMesh *dm, @@ -2772,6 +2773,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, attribs->tface[a].array = tfdata->layers[layer].data; attribs->tface[a].emOffset = tfdata->layers[layer].offset; attribs->tface[a].glIndex = gattribs->layer[b].glindex; + attribs->tface[a].glTexco = gattribs->layer[b].gltexco; } } else if(gattribs->layer[b].type == CD_MCOL) { @@ -2812,6 +2814,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, attribs->orco.array = vdata->layers[layer].data; attribs->orco.emOffset = vdata->layers[layer].offset; attribs->orco.glIndex = gattribs->layer[b].glindex; + attribs->orco.glTexco = gattribs->layer[b].gltexco; } } } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 8aa816f9cb5..ebe7325d96a 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1245,6 +1245,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p sim.ob= par; sim.psys= psys; sim.psmd= psys_get_modifier(par, psys); + /* make sure emitter imat is in global coordinates instead of render view coordinates */ + invert_m4_m4(par->imat, par->obmat); /* first check for loops (particle system object used as dupli object) */ if(part->ren_as == PART_DRAW_OB) { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8b4bbbd3c83..7e2097d1233 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -330,28 +330,45 @@ static int handle_subversion_warning(Main *main) return 1; } +static void keymap_item_free(wmKeyMapItem *kmi) +{ + if(kmi->properties) { + IDP_FreeProperty(kmi->properties); + MEM_freeN(kmi->properties); + } + if(kmi->ptr) + MEM_freeN(kmi->ptr); +} + void BKE_userdef_free(void) { wmKeyMap *km; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; - for(km=U.keymaps.first; km; km=km->next) { - for(kmi=km->items.first; kmi; kmi=kmi->next) { - if(kmi->properties) { - IDP_FreeProperty(kmi->properties); - MEM_freeN(kmi->properties); + for(km=U.user_keymaps.first; km; km=km->next) { + for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) { + if(kmdi->add_item) { + keymap_item_free(kmdi->add_item); + MEM_freeN(kmdi->add_item); + } + if(kmdi->remove_item) { + keymap_item_free(kmdi->remove_item); + MEM_freeN(kmdi->remove_item); } - if(kmi->ptr) - MEM_freeN(kmi->ptr); } + for(kmi=km->items.first; kmi; kmi=kmi->next) + keymap_item_free(kmi); + + BLI_freelistN(&km->diff_items); BLI_freelistN(&km->items); } BLI_freelistN(&U.uistyles); BLI_freelistN(&U.uifonts); BLI_freelistN(&U.themes); - BLI_freelistN(&U.keymaps); + BLI_freelistN(&U.user_keymaps); BLI_freelistN(&U.addons); } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 57a155987d1..95f46a822f6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -995,6 +995,50 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); } +static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal) +{ + int b; + + /* orco texture coordinates */ + if(attribs->totorco) { + if(attribs->orco.glTexco) + glTexCoord3fv(attribs->orco.array[index]); + else + glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]); + } + + /* uv texture coordinates */ + for(b = 0; b < attribs->tottface; b++) { + MTFace *tf = &attribs->tface[b].array[a]; + + if(attribs->tface[b].glTexco) + glTexCoord2fv(tf->uv[vert]); + else + glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]); + } + + /* vertex colors */ + for(b = 0; b < attribs->totmcol; b++) { + MCol *cp = &attribs->mcol[b].array[a*4 + vert]; + GLubyte col[4]; + col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; + glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col); + } + + /* tangent for normal mapping */ + if(attribs->tottang) { + float *tang = attribs->tang.array[a*4 + vert]; + glVertexAttrib4fvARB(attribs->tang.glIndex, tang); + } + + /* vertex normal */ + if(smoothnormal) + glNormal3sv(mvert[index].no); + + /* vertex coordinate */ + glVertex3fv(mvert[index].co); +} + static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; @@ -1085,37 +1129,14 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo } } -#define PASSVERT(index, vert) { \ - if(attribs.totorco) \ - glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \ - for(b = 0; b < attribs.tottface; b++) { \ - MTFace *tf = &attribs.tface[b].array[a]; \ - glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \ - } \ - for(b = 0; b < attribs.totmcol; b++) { \ - MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \ - GLubyte col[4]; \ - col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \ - glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \ - } \ - if(attribs.tottang) { \ - float *tang = attribs.tang.array[a*4 + vert]; \ - glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \ - } \ - if(smoothnormal) \ - glNormal3sv(mvert[index].no); \ - glVertex3fv(mvert[index].co); \ - } + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal); + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); - PASSVERT(mface->v1, 0); - PASSVERT(mface->v2, 1); - PASSVERT(mface->v3, 2); if(mface->v4) - PASSVERT(mface->v4, 3) + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal); else - PASSVERT(mface->v3, 2) - -#undef PASSVERT + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal); } glEnd(); } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ea055e90b45..3a86389dba7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -923,7 +923,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d for(i = 0; i < dm->getNumVerts(dm); i++) { - maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0)); + maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0f)); } clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist ); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d39be9d683c..667e0850111 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -301,6 +301,7 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node for (fcu= adt->drivers.first; fcu; fcu= fcu->next) { ChannelDriver *driver= fcu->driver; DriverVar *dvar; + int isdata_fcu = isdata || (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")); /* loop over variables to get the target relationships */ for (dvar= driver->variables.first; dvar; dvar= dvar->next) { @@ -320,14 +321,14 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node ( ((dtar->rna_path) && strstr(dtar->rna_path, "pose.bones[")) || ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) )) { - dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver"); + dag_add_relation(dag, node1, node, isdata_fcu?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver"); } /* check if ob data */ else if (dtar->rna_path && strstr(dtar->rna_path, "data.")) - dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver"); + dag_add_relation(dag, node1, node, isdata_fcu?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver"); /* normal */ else - dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver"); + dag_add_relation(dag, node1, node, isdata_fcu?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver"); } } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 8f57490d057..c2ed6468643 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1369,6 +1369,11 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) Curve *cu= ob->data; ListBase *dispbase; + /* The same check for duplis as in do_makeDispListCurveTypes. + Happens when curve used for constraint/bevel was converted to mesh. + check there is still needed for render displist and orco displists. */ + if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; + freedisplist(&(ob->disp)); dispbase= &(ob->disp); freedisplist(dispbase); diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index d6a9d950015..13e13fbc3ff 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1002,7 +1002,7 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar) /* get property to read from, and get value as appropriate */ if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { - if(RNA_property_array_check(&ptr, prop)) { + if(RNA_property_array_check(prop)) { /* array */ if (index < RNA_property_array_length(&ptr, prop)) { switch (RNA_property_type(prop)) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 51f1cd61e7c..fe26c0ccd2d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -195,6 +195,18 @@ void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData) } } +void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData) +{ + ModifierData *md = ob->modifiers.first; + + for (; md; md=md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if(mti->foreachTexLink) + mti->foreachTexLink(md, ob, walk, userData); + } +} + void modifier_copyData(ModifierData *md, ModifierData *target) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index c02b5dda9ce..bd238e72d0c 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1582,7 +1582,7 @@ void BKE_nla_tweakmode_exit (AnimData *adt) /* Baking Tools ------------------------------------------- */ -static void BKE_nla_bake (Scene *scene, ID *UNUSED(id), AnimData *adt, int UNUSED(flag)) +static void UNUSED_FUNCTION(BKE_nla_bake) (Scene *scene, ID *UNUSED(id), AnimData *adt, int UNUSED(flag)) { /* verify that data is valid diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 13469e0b58b..5f1a6c911bc 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3243,7 +3243,7 @@ static int node_animation_properties(bNodeTree *ntree, bNode *node) int driven, len=1, index; prop = (PropertyRNA *)link; - if (RNA_property_array_check(&ptr, prop)) + if (RNA_property_array_check(prop)) len = RNA_property_array_length(&ptr, prop); for (index=0; index<len; index++) { @@ -3261,7 +3261,7 @@ static int node_animation_properties(bNodeTree *ntree, bNode *node) RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); prop = RNA_struct_find_property(&ptr, "default_value"); - if (RNA_property_array_check(&ptr, prop)) + if (RNA_property_array_check(prop)) len = RNA_property_array_length(&ptr, prop); for (index=0; index<len; index++) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 51971f8d72d..3099b26357a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -4398,6 +4398,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa copy_m3_m4(nmat, ob->imat); transpose_m3(nmat); mul_m3_v3(nmat, nor); + normalize_v3(nor); /* make sure that we get a proper side vector */ if(fabs(dot_v3v3(nor,vec))>0.999999) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index d6a152a5280..3aebbea789f 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -699,6 +699,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range) seq->len = 0; } seq->strip->len = seq->len; + break; case SEQ_SOUND: #ifdef WITH_AUDASPACE if(!seq->sound) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 036ba34d0c8..493baebd197 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1005,7 +1005,7 @@ void autotexname(Tex *tex) Tex *give_current_object_texture(Object *ob) { - Material *ma; + Material *ma, *node_ma; Tex *tex= NULL; if(ob==NULL) return NULL; @@ -1015,6 +1015,10 @@ Tex *give_current_object_texture(Object *ob) tex= give_current_lamp_texture(ob->data); } else { ma= give_current_material(ob, ob->actcol); + + if((node_ma=give_node_material(ma))) + ma= node_ma; + tex= give_current_material_texture(ma); } @@ -1080,17 +1084,6 @@ Tex *give_current_material_texture(Material *ma) tex= (Tex *)node->id; ma= NULL; } - else { - node= nodeGetActiveID(ma->nodetree, ID_MA); - if(node) { - ma= (Material*)node->id; - if(ma) { - mtex= ma->mtex[(int)(ma->texact)]; - if(mtex) tex= mtex->tex; - } - } - } - return tex; } if(ma) { @@ -1165,11 +1158,6 @@ void set_current_material_texture(Material *ma, Tex *newtex) id_us_plus(&newtex->id); ma= NULL; } - else { - node= nodeGetActiveID(ma->nodetree, ID_MA); - if(node) - ma= (Material*)node->id; - } } if(ma) { int act= (int)ma->texact; @@ -1198,16 +1186,8 @@ int has_current_material_texture(Material *ma) if(ma && ma->use_nodes && ma->nodetree) { node= nodeGetActiveID(ma->nodetree, ID_TE); - if(node) { + if(node) return 1; - } - else { - node= nodeGetActiveID(ma->nodetree, ID_MA); - if(node) - ma= (Material*)node->id; - else - ma= NULL; - } } return (ma != NULL); diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index b89e576a562..a9792bc44fa 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -136,7 +136,7 @@ static struct bUnitDef buImperialLenDef[] = { {"yard", "yards", "yd", NULL, "Yards", UN_SC_YD, 0.0, B_UNIT_DEF_NONE}, {"foot", "feet", "'", "ft", "Feet", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */ {"inch", "inches", "\"", "in", "Inches", UN_SC_IN, 0.0, B_UNIT_DEF_NONE}, - {"thou", "thous", "mil", NULL, "Thous", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, + {"thou", "thou", "thou", "mil", "Thou", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, /* plural for thou has no 's' */ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} }; static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef)/sizeof(bUnitDef)}; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 4db53999f10..fe7a7a18177 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -658,10 +658,12 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report switch(ffmpeg_type) { case FFMPEG_AVI: case FFMPEG_MOV: - case FFMPEG_OGG: case FFMPEG_MKV: fmt->video_codec = ffmpeg_codec; break; + case FFMPEG_OGG: + fmt->video_codec = CODEC_ID_THEORA; + break; case FFMPEG_DV: fmt->video_codec = CODEC_ID_DVVIDEO; break; @@ -1310,6 +1312,9 @@ void ffmpeg_verify_image_type(RenderData *rd) /* Don't set preset, disturbs render resolution. * ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */ } + if(rd->ffcodecdata.type == FFMPEG_OGG) { + rd->ffcodecdata.type = FFMPEG_MPEG2; + } audio= 1; } diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index dcc71fa1258..e4afc6ad79b 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -53,14 +53,14 @@ typedef void (*GHashValFreeFP) (void *val); typedef struct Entry { struct Entry *next; - + void *key, *val; } Entry; typedef struct GHash { GHashHashFP hashfp; GHashCmpFP cmpfp; - + Entry **buckets; struct BLI_mempool *entrypool; int nbuckets, nentries, cursize; @@ -72,15 +72,15 @@ typedef struct GHashIterator { struct Entry *curEntry; } GHashIterator; -GHash* BLI_ghash_new (GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info); -void BLI_ghash_free (GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); - -//BM_INLINE void BLI_ghash_insert (GHash *gh, void *key, void *val); -//BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); -//BM_INLINE void* BLI_ghash_lookup (GHash *gh, void *key); -//BM_INLINE int BLI_ghash_haskey (GHash *gh, void *key); +/* *** */ -int BLI_ghash_size (GHash *gh); +GHash* BLI_ghash_new (GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info); +void BLI_ghash_free (GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +void BLI_ghash_insert(GHash *gh, void *key, void *val); +void * BLI_ghash_lookup(GHash *gh, const void *key); +int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); +int BLI_ghash_haskey(GHash *gh, void *key); +int BLI_ghash_size (GHash *gh); /* *** */ @@ -149,127 +149,10 @@ unsigned int BLI_ghashutil_strhash (const void *key); int BLI_ghashutil_strcmp (const void *a, const void *b); unsigned int BLI_ghashutil_inthash (const void *ptr); -int BLI_ghashutil_intcmp(const void *a, const void *b); - -/*begin of macro-inlined functions*/ -extern unsigned int hashsizes[]; - -#if 0 -#define BLI_ghash_insert(gh, _k, _v){\ - unsigned int _hash= (gh)->hashfp(_k)%gh->nbuckets;\ - Entry *_e= BLI_mempool_alloc((gh)->entrypool);\ - _e->key= _k;\ - _e->val= _v;\ - _e->next= (gh)->buckets[_hash];\ - (gh)->buckets[_hash]= _e;\ - if (++(gh)->nentries>(gh)->nbuckets*3) {\ - Entry *_e, **_old= (gh)->buckets;\ - int _i, _nold= (gh)->nbuckets;\ - (gh)->nbuckets= hashsizes[++(gh)->cursize];\ - (gh)->buckets= malloc((gh)->nbuckets*sizeof(*(gh)->buckets));\ - memset((gh)->buckets, 0, (gh)->nbuckets*sizeof(*(gh)->buckets));\ - for (_i=0; _i<_nold; _i++) {\ - for (_e= _old[_i]; _e;) {\ - Entry *_n= _e->next;\ - _hash= (gh)->hashfp(_e->key)%(gh)->nbuckets;\ - _e->next= (gh)->buckets[_hash];\ - (gh)->buckets[_hash]= _e;\ - _e= _n;\ - }\ - }\ - free(_old); } } -#endif - -/*---------inlined functions---------*/ -BM_INLINE void BLI_ghash_insert(GHash *gh, void *key, void *val) { - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e= (Entry*) BLI_mempool_alloc(gh->entrypool); - - e->key= key; - e->val= val; - e->next= gh->buckets[hash]; - gh->buckets[hash]= e; - - if (++gh->nentries>(float)gh->nbuckets/2) { - Entry **old= gh->buckets; - int i, nold= gh->nbuckets; - - gh->nbuckets= hashsizes[++gh->cursize]; - gh->buckets= (Entry**)MEM_mallocN(gh->nbuckets*sizeof(*gh->buckets), "buckets"); - memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets)); - - for (i=0; i<nold; i++) { - for (e= old[i]; e;) { - Entry *n= e->next; - - hash= gh->hashfp(e->key)%gh->nbuckets; - e->next= gh->buckets[hash]; - gh->buckets[hash]= e; - - e= n; - } - } - - MEM_freeN(old); - } -} - -BM_INLINE void* BLI_ghash_lookup(GHash *gh, const void *key) -{ - if(gh) { - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e; - - for (e= gh->buckets[hash]; e; e= e->next) - if (gh->cmpfp(key, e->key)==0) - return e->val; - } - return NULL; -} - -BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) -{ - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e; - Entry *p = NULL; - - for (e= gh->buckets[hash]; e; e= e->next) { - if (gh->cmpfp(key, e->key)==0) { - Entry *n= e->next; - - if (keyfreefp) keyfreefp(e->key); - if (valfreefp) valfreefp(e->val); - BLI_mempool_free(gh->entrypool, e); - - - e= n; - if (p) - p->next = n; - else - gh->buckets[hash] = n; - - --gh->nentries; - return 1; - } - p = e; - } - - return 0; -} - -BM_INLINE int BLI_ghash_haskey(GHash *gh, void *key) { - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e; - - for (e= gh->buckets[hash]; e; e= e->next) - if (gh->cmpfp(key, e->key)==0) - return 1; - - return 0; -} +int BLI_ghashutil_intcmp (const void *a, const void *b); #ifdef __cplusplus } #endif -#endif +#endif /* BLI_GHASH_H */ diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 9af55601ff7..28ebb254f2a 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -184,6 +184,12 @@ #endif #ifdef __GNUC__ +# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x +#else +# define UNUSED_FUNCTION(x) UNUSED_ ## x +#endif + +#ifdef __GNUC__ # define WARN_UNUSED __attribute__((warn_unused_result)) #else # define WARN_UNUSED diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index ff08ef4dba9..bfee350037a 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -49,8 +49,6 @@ unsigned int hashsizes[]= { /***/ -/***/ - GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) { GHash *gh= MEM_mallocN(sizeof(*gh), info); gh->hashfp= hashfp; @@ -67,14 +65,96 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) { return gh; } -#ifdef BLI_ghash_insert -#undef BLI_ghash_insert -#endif - int BLI_ghash_size(GHash *gh) { return gh->nentries; } +void BLI_ghash_insert(GHash *gh, void *key, void *val) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e= (Entry*) BLI_mempool_alloc(gh->entrypool); + + e->key= key; + e->val= val; + e->next= gh->buckets[hash]; + gh->buckets[hash]= e; + + if (++gh->nentries>(float)gh->nbuckets/2) { + Entry **old= gh->buckets; + int i, nold= gh->nbuckets; + + gh->nbuckets= hashsizes[++gh->cursize]; + gh->buckets= (Entry**)MEM_mallocN(gh->nbuckets*sizeof(*gh->buckets), "buckets"); + memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets)); + + for (i=0; i<nold; i++) { + for (e= old[i]; e;) { + Entry *n= e->next; + + hash= gh->hashfp(e->key)%gh->nbuckets; + e->next= gh->buckets[hash]; + gh->buckets[hash]= e; + + e= n; + } + } + + MEM_freeN(old); + } +} + +void *BLI_ghash_lookup(GHash *gh, const void *key) { + if(gh) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return e->val; + } + return NULL; +} + +int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) +{ + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + Entry *p = NULL; + + for (e= gh->buckets[hash]; e; e= e->next) { + if (gh->cmpfp(key, e->key)==0) { + Entry *n= e->next; + + if (keyfreefp) keyfreefp(e->key); + if (valfreefp) valfreefp(e->val); + BLI_mempool_free(gh->entrypool, e); + + /* correct but 'e' isnt used before return */ + /* e= n; */ /*UNUSED*/ + if (p) + p->next = n; + else + gh->buckets[hash] = n; + + --gh->nentries; + return 1; + } + p = e; + } + + return 0; +} + +int BLI_ghash_haskey(GHash *gh, void *key) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return 1; + + return 0; +} + void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { int i; diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c index 16f0c86c449..f0e81d6b5e9 100644 --- a/source/blender/blenlib/intern/jitter.c +++ b/source/blender/blenlib/intern/jitter.c @@ -53,10 +53,10 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1) y = jit1[i+1]; for (j = 2*num-2; j>=0 ; j-=2) { if (i != j){ - vecx = jit1[j] - x - 1.0; - vecy = jit1[j+1] - y - 1.0; + vecx = jit1[j] - x - 1.0f; + vecy = jit1[j+1] - y - 1.0f; for (k = 3; k>0 ; k--){ - if( fabs(vecx)<rad1 && fabs(vecy)<rad1) { + if( fabsf(vecx)<rad1 && fabsf(vecy)<rad1) { len= sqrt(vecx*vecx + vecy*vecy); if(len>0 && len<rad1) { len= len/rad1; @@ -64,9 +64,9 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1) dvecy += vecy/len; } } - vecx += 1.0; + vecx += 1.0f; - if( fabs(vecx)<rad1 && fabs(vecy)<rad1) { + if( fabsf(vecx)<rad1 && fabsf(vecy)<rad1) { len= sqrt(vecx*vecx + vecy*vecy); if(len>0 && len<rad1) { len= len/rad1; @@ -74,9 +74,9 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1) dvecy += vecy/len; } } - vecx += 1.0; + vecx += 1.0f; - if( fabs(vecx)<rad1 && fabs(vecy)<rad1) { + if( fabsf(vecx)<rad1 && fabsf(vecy)<rad1) { len= sqrt(vecx*vecx + vecy*vecy); if(len>0 && len<rad1) { len= len/rad1; @@ -84,16 +84,16 @@ void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1) dvecy += vecy/len; } } - vecx -= 2.0; - vecy += 1.0; + vecx -= 2.0f; + vecy += 1.0f; } } } - x -= dvecx/18.0 ; - y -= dvecy/18.0; - x -= floor(x) ; - y -= floor(y); + x -= dvecx/18.0f; + y -= dvecy/18.0f; + x -= floorf(x) ; + y -= floorf(y); jit2[i] = x; jit2[i+1] = y; } @@ -111,28 +111,28 @@ void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2) y = jit1[i+1]; for (j =2*num -2; j>= 0 ; j-=2){ if (i != j){ - vecx = jit1[j] - x - 1.0; - vecy = jit1[j+1] - y - 1.0; + vecx = jit1[j] - x - 1.0f; + vecy = jit1[j+1] - y - 1.0f; - if( fabs(vecx)<rad2) dvecx+= vecx*rad2; - vecx += 1.0; - if( fabs(vecx)<rad2) dvecx+= vecx*rad2; - vecx += 1.0; - if( fabs(vecx)<rad2) dvecx+= vecx*rad2; + if( fabsf(vecx)<rad2) dvecx+= vecx*rad2; + vecx += 1.0f; + if( fabsf(vecx)<rad2) dvecx+= vecx*rad2; + vecx += 1.0f; + if( fabsf(vecx)<rad2) dvecx+= vecx*rad2; - if( fabs(vecy)<rad2) dvecy+= vecy*rad2; - vecy += 1.0; - if( fabs(vecy)<rad2) dvecy+= vecy*rad2; - vecy += 1.0; - if( fabs(vecy)<rad2) dvecy+= vecy*rad2; + if( fabsf(vecy)<rad2) dvecy+= vecy*rad2; + vecy += 1.0f; + if( fabsf(vecy)<rad2) dvecy+= vecy*rad2; + vecy += 1.0f; + if( fabsf(vecy)<rad2) dvecy+= vecy*rad2; } } - x -= dvecx/2 ; - y -= dvecy/2; - x -= floor(x) ; - y -= floor(y); + x -= dvecx/2.0f; + y -= dvecy/2.0f; + x -= floorf(x) ; + y -= floorf(y); jit2[i] = x; jit2[i+1] = y; } @@ -148,17 +148,17 @@ void BLI_initjit(float *jitarr, int num) if(num==0) return; jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit"); - rad1= 1.0/sqrt((float)num); - rad2= 1.0/((float)num); - rad3= sqrt((float)num)/((float)num); + rad1= 1.0f/sqrtf((float)num); + rad2= 1.0f/((float)num); + rad3= sqrtf((float)num)/((float)num); BLI_srand(31415926 + num); x= 0; for(i=0; i<2*num; i+=2) { - jitarr[i]= x+ rad1*(0.5-BLI_drand()); - jitarr[i+1]= ((float)i/2)/num +rad1*(0.5-BLI_drand()); + jitarr[i]= x+ rad1*(float)(0.5-BLI_drand()); + jitarr[i+1]= ((float)i/2)/num +rad1*(float)(0.5-BLI_drand()); x+= rad3; - x -= floor(x); + x -= floorf(x); } for (i=0 ; i<24 ; i++) { @@ -171,8 +171,8 @@ void BLI_initjit(float *jitarr, int num) /* finally, move jittertab to be centered around (0,0) */ for(i=0; i<2*num; i+=2) { - jitarr[i] -= 0.5; - jitarr[i+1] -= 0.5; + jitarr[i] -= 0.5f; + jitarr[i+1] -= 0.5f; } } diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0c9508efc27..707adc67ca3 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -417,7 +417,7 @@ int isect_line_sphere_v3(const float l1[3], const float l2[3], madd_v3_v3v3fl(r_p1, l1, ldir, mu); return 1; } - else if (i > 0.0) { + else if (i > 0.0f) { const float i_sqrt= sqrt(i); /* avoid calc twice */ /* first intersection */ @@ -471,7 +471,7 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2], madd_v2_v2v2fl(r_p1, l1, ldir, mu); return 1; } - else if (i > 0.0) { + else if (i > 0.0f) { const float i_sqrt= sqrt(i); /* avoid calc twice */ /* first intersection */ @@ -2025,7 +2025,7 @@ void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const f } if(IS_ZERO(denom)==0) - uv[1]= (float) (( (1-uv[0])*(st0[i]-st[i]) + uv[0]*(st1[i]-st[i]) ) / denom); + uv[1]= (float) (( (1.0f-uv[0])*(st0[i]-st[i]) + uv[0]*(st1[i]-st[i]) ) / denom); } } diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index dfd715ccbf2..e3e507d016a 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -213,7 +213,7 @@ void quat_to_mat4(float m[][4], const float q[4]) double q0, q1, q2, q3, qda,qdb,qdc,qaa,qab,qac,qbb,qbc,qcc; #ifdef DEBUG - if(!((q0=dot_qtqt(q, q))==0.0f || (fabsf(q0-1.0f) < (float)QUAT_EPSILON))) { + if(!((q0=dot_qtqt(q, q))==0.0f || (fabs(q0-1.0) < QUAT_EPSILON))) { fprintf(stderr, "Warning! quat_to_mat4() called with non-normalized: size %.8f *** report a bug ***\n", (float)q0); } #endif @@ -492,8 +492,8 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag) else angle= (float)(-0.5*atan2(-fp[0], -fp[1])); } - co= (float)cos(angle); - si= (float)(sin(angle)/len1); + co= cosf(angle); + si= sinf(angle)/len1; q2[0]= co; q2[1]= x2*si; q2[2]= y2*si; diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index 17b07b49309..31ae8adc2d4 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -233,10 +233,10 @@ int BLI_isect_rcti(rcti *src1, rcti *src2, rcti *dest) void BLI_copy_rcti_rctf(rcti *tar, const rctf *src) { - tar->xmin= floor(src->xmin + 0.5); - tar->xmax= floor((src->xmax - src->xmin) + 0.5); - tar->ymin= floor(src->ymin + 0.5); - tar->ymax= floor((src->ymax - src->ymin) + 0.5); + tar->xmin= floor(src->xmin + 0.5f); + tar->xmax= floor((src->xmax - src->xmin) + 0.5f); + tar->ymin= floor(src->ymin + 0.5f); + tar->ymax= floor((src->ymax - src->ymin) + 0.5f); } void print_rctf(const char *str, rctf *rect) diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 47a07d86e66..b159106f748 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -288,7 +288,7 @@ static short testedgeside(float *v1, float *v2, float *v3) inp= (v2[cox]-v1[cox])*(v1[coy]-v3[coy]) +(v1[coy]-v2[coy])*(v1[cox]-v3[cox]); - if(inp<0.0) return 0; + if(inp < 0.0f) return 0; else if(inp==0) { if(v1[cox]==v3[cox] && v1[coy]==v3[coy]) return 0; if(v2[cox]==v3[cox] && v2[coy]==v3[coy]) return 0; @@ -312,8 +312,8 @@ static short addedgetoscanvert(ScFillVert *sc, EditEdge *eed) y= eed->v1->co[coy]; fac1= eed->v2->co[coy]-y; - if(fac1==0.0) { - fac1= 1.0e10*(eed->v2->co[cox]-x); + if(fac1==0.0f) { + fac1= 1.0e10f*(eed->v2->co[cox]-x); } else fac1= (x-eed->v2->co[cox])/fac1; @@ -324,8 +324,8 @@ static short addedgetoscanvert(ScFillVert *sc, EditEdge *eed) if(ed->v2==eed->v2) return 0; fac= ed->v2->co[coy]-y; - if(fac==0.0) { - fac= 1.0e10*(ed->v2->co[cox]-x); + if(fac==0.0f) { + fac= 1.0e10f*(ed->v2->co[cox]-x); } else fac= (x-ed->v2->co[cox])/fac; @@ -443,7 +443,7 @@ static void testvertexnearedge(void) vec2[1]= eed->v2->co[coy]; if(boundinsideEV(eed,eve)) { dist= dist_to_line_v2(vec1,vec2,vec3); - if(dist<COMPLIMIT) { + if(dist<(float)COMPLIMIT) { /* new edge */ ed1= BLI_addfilledge(eed->v1, eve); @@ -816,7 +816,7 @@ int BLI_edgefill(short mat_nr) if(v2) { if( compare_v3v3(v2, eve->co, COMPLIMIT)==0) { len= normal_tri_v3( norm,v1, v2, eve->co); - if(len != 0.0) break; + if(len != 0.0f) break; } } else if(compare_v3v3(v1, eve->co, COMPLIMIT)==0) { @@ -825,7 +825,7 @@ int BLI_edgefill(short mat_nr) eve= eve->next; } - if(len==0.0) return 0; /* no fill possible */ + if(len==0.0f) return 0; /* no fill possible */ norm[0]= fabs(norm[0]); norm[1]= fabs(norm[1]); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 32b353508ec..62209e88dc3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4764,6 +4764,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) wm->keyconfigs.first= wm->keyconfigs.last= NULL; wm->defaultconf= NULL; + wm->addonconf= NULL; + wm->userconf= NULL; wm->jobs.first= wm->jobs.last= NULL; wm->drags.first= wm->drags.last= NULL; @@ -11706,8 +11708,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Tex *tex; for(tex= main->tex.first; tex; tex= tex->id.next) { if(tex->pd) { - if (tex->pd->falloff_speed_scale == 0.0) - tex->pd->falloff_speed_scale = 100.0; + if (tex->pd->falloff_speed_scale == 0.0f) + tex->pd->falloff_speed_scale = 100.0f; if (!tex->pd->falloff_curve) { tex->pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1); @@ -11800,33 +11802,57 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_library(fd, main); /* only init users */ } +static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi) +{ + kmi->properties= newdataadr(fd, kmi->properties); + if(kmi->properties) + IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + kmi->ptr= NULL; + kmi->flag &= ~KMI_UPDATE; +} static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) { UserDef *user; wmKeyMap *keymap; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; bfd->user= user= read_struct(fd, bhead, "user def"); /* read all data into fd->datamap */ bhead= read_data_into_oldnewmap(fd, bhead, "user def"); + if(user->keymaps.first) { + /* backwards compatibility */ + user->user_keymaps= user->keymaps; + user->keymaps.first= user->keymaps.last= NULL; + } + link_list(fd, &user->themes); - link_list(fd, &user->keymaps); + link_list(fd, &user->user_keymaps); link_list(fd, &user->addons); - for(keymap=user->keymaps.first; keymap; keymap=keymap->next) { + for(keymap=user->user_keymaps.first; keymap; keymap=keymap->next) { keymap->modal_items= NULL; keymap->poll= NULL; + keymap->flag &= ~KEYMAP_UPDATE; + link_list(fd, &keymap->diff_items); link_list(fd, &keymap->items); - for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - kmi->properties= newdataadr(fd, kmi->properties); - if(kmi->properties) - IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); - kmi->ptr= NULL; + + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + kmdi->remove_item= newdataadr(fd, kmdi->remove_item); + kmdi->add_item= newdataadr(fd, kmdi->add_item); + + if(kmdi->remove_item) + direct_link_keymapitem(fd, kmdi->remove_item); + if(kmdi->add_item) + direct_link_keymapitem(fd, kmdi->add_item); } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + direct_link_keymapitem(fd, kmi); } // XXX diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5285a1a0c74..bba5ff66658 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -718,11 +718,19 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon } } +static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi) +{ + writestruct(wd, DATA, "wmKeyMapItem", 1, kmi); + if(kmi->properties) + IDP_WriteProperty(kmi->properties, wd); +} + static void write_userdef(WriteData *wd) { bTheme *btheme; wmKeyMap *keymap; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; bAddon *bext; uiStyle *style; @@ -731,15 +739,19 @@ static void write_userdef(WriteData *wd) for(btheme= U.themes.first; btheme; btheme=btheme->next) writestruct(wd, DATA, "bTheme", 1, btheme); - for(keymap= U.keymaps.first; keymap; keymap=keymap->next) { + for(keymap= U.user_keymaps.first; keymap; keymap=keymap->next) { writestruct(wd, DATA, "wmKeyMap", 1, keymap); - for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - writestruct(wd, DATA, "wmKeyMapItem", 1, kmi); - - if(kmi->properties) - IDP_WriteProperty(kmi->properties, wd); + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + writestruct(wd, DATA, "wmKeyMapDiffItem", 1, kmdi); + if(kmdi->remove_item) + write_keymapitem(wd, kmdi->remove_item); + if(kmdi->add_item) + write_keymapitem(wd, kmdi->add_item); } + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + write_keymapitem(wd, kmi); } for(bext= U.addons.first; bext; bext=bext->next) diff --git a/source/blender/blenpluginapi/SConscript b/source/blender/blenpluginapi/SConscript index 32e69069bb0..7c7c1318a6e 100644 --- a/source/blender/blenpluginapi/SConscript +++ b/source/blender/blenpluginapi/SConscript @@ -11,7 +11,7 @@ if env['WITH_BF_QUICKTIME']: defs.append('WITH_QUICKTIME') incs += ' ' + env['BF_QUICKTIME_INC'] -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript index beabd912a20..b7f9a263bc1 100644 --- a/source/blender/editors/armature/SConscript +++ b/source/blender/editors/armature/SConscript @@ -7,7 +7,7 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf ../ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../gpu ../../makesrna #/intern/opennl/extern' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index 3d6888d87dc..69b7fff3607 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -1000,7 +1000,7 @@ static short pose_propagate_get_refVal (Object *ob, FCurve *fcu, float *value) /* resolve the property... */ if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) { - if (RNA_property_array_check(&ptr, prop)) { + if (RNA_property_array_check(prop)) { /* array */ if (fcu->array_index < RNA_property_array_length(&ptr, prop)) { found= TRUE; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 28a54b20277..169443d855f 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1615,7 +1615,12 @@ static int gpencil_area_exists(bContext *C, ScrArea *satest) static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p= op->customdata; - int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */ + //int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */ + /* currently, grease pencil conflicts with such operators as undo and set object mode + which makes behavior of operator totally unpredictable and crash for some cases. + the only way to solve this proper is to ger rid of pointers to data which can + chage stored in operator custom data (sergey) */ + int estate = OPERATOR_RUNNING_MODAL; // if (event->type == NDOF_MOTION) // return OPERATOR_PASS_THROUGH; @@ -1722,13 +1727,18 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event) /* standard undo/redo shouldn't be allowed to execute or else it causes crashes, so catch it here */ // FIXME: this is a hardcoded hotkey that can't be changed // TODO: catch redo as well, but how? - if (event->type == ZKEY) { + if (event->type == ZKEY && event->val == KM_RELEASE) { /* oskey = cmd key on macs as they seem to use cmd-z for undo as well? */ if ((event->ctrl) || (event->oskey)) { /* just delete last stroke, which will look like undo to the end user */ //printf("caught attempted undo event... deleting last stroke \n"); gpencil_frame_delete_laststroke(p->gpl, p->gpf); - + /* undoing the last line can free p->gpf + * note, could do this in a bit more of an elegant way then a search but it at least prevents a crash */ + if(BLI_findindex(&p->gpl->frames, p->gpf) == -1) { + p->gpf= NULL; + } + /* event handled, so force refresh */ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ estate = OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index dfa457c22de..cc4dd6330fb 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -33,12 +33,14 @@ #ifndef ED_NODE_H #define ED_NODE_H +struct ID; +struct Main; struct Material; struct Scene; struct Tex; struct bContext; struct bNode; -struct ID; +struct bNodeTree; struct ScrArea; /* drawnode.c */ @@ -55,6 +57,8 @@ void ED_node_texture_default(struct Tex *tex); void ED_node_link_intersect_test(struct ScrArea *sa, int test); void ED_node_link_insert(struct ScrArea *sa); +void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); + /* node ops.c */ void ED_operatormacros_node(void); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 28d0a9520b2..c646ec55506 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -108,7 +108,7 @@ int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, fl struct Object *ED_object_add_type(struct bContext *C, int type, float *loc, float *rot, int enter_editmode, unsigned int layer); void ED_object_single_users(struct Main *bmain, struct Scene *scene, int full); - +void ED_object_single_user(struct Scene *scene, struct Object *ob); /* object motion paths */ void ED_objects_clear_paths(struct bContext *C); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 61e19655f8d..3fe012ea73e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -164,6 +164,9 @@ typedef struct uiLayout uiLayout; /* scale fixed button widths by this to account for DPI * 8.4852 == sqrtf(72.0f)) */ #define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f) +#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f) +/* 16 to copy ICON_DEFAULT_HEIGHT */ +#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC) /* Button types, bits stored in 1 value... and a short even! - bits 0-4: bitnr (0-31) @@ -407,6 +410,7 @@ uiBut *uiDefButBitS(uiBlock *block, int type, int bit, int retval, const char *s uiBut *uiDefButC(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip); @@ -426,6 +430,7 @@ uiBut *uiDefIconButBitS(uiBlock *block, int type, int bit, int retval, int icon, uiBut *uiDefIconButC(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip); uiBut *uiDefIconTextBut(uiBlock *block, @@ -444,6 +449,7 @@ uiBut *uiDefIconTextButBitS(uiBlock *block, int type, int bit, int retval, int i uiBut *uiDefIconTextButC(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip); +uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip); /* for passing inputs to ButO buttons */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8aed0d58a07..a5ceb8bdb19 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -710,6 +710,27 @@ int uiButActiveOnly(const bContext *C, uiBlock *block, uiBut *but) return 1; } +/* use to check if we need to disable undo, but dont make any changes + * returns FALSE if undo needs to be disabled. */ +static int ui_but_is_rna_undo(uiBut *but) +{ + if(but->rnapoin.id.data) { + /* avoid undo push for buttons who's ID are screen or wm level + * we could disable undo for buttons with no ID too but may have + * unforseen conciquences, so best check for ID's we _know_ are not + * handled by undo - campbell */ + ID *id= but->rnapoin.id.data; + if(ELEM(GS(id->name), ID_SCR, ID_WM)) { + return FALSE; + } + else { + return TRUE; + } + } + + return TRUE; +} + /* assigns automatic keybindings to menu items for fast access * (underline key in menu) */ static void ui_menu_block_set_keyaccels(uiBlock *block) @@ -1245,14 +1266,14 @@ int ui_is_but_float(uiBut *but) int ui_is_but_unit(uiBut *but) { - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); - int unit_type= uiButGetUnitType(but); + UnitSettings *unit= but->block->unit; + const int unit_type= uiButGetUnitType(but); if(unit_type == PROP_UNIT_NONE) return 0; #if 1 // removed so angle buttons get correct snapping - if (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION) + if (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION) return 0; #endif @@ -1260,7 +1281,7 @@ int ui_is_but_unit(uiBut *but) if (unit_type == PROP_UNIT_TIME) return 0; - if (scene->unit.system == USER_UNIT_NONE) { + if (unit->system == USER_UNIT_NONE) { if (unit_type != PROP_UNIT_ROTATION) { return 0; } @@ -1293,19 +1314,19 @@ double ui_get_but_val(uiBut *but) switch(RNA_property_type(prop)) { case PROP_BOOLEAN: - if(RNA_property_array_length(&but->rnapoin, prop)) + if(RNA_property_array_check(prop)) value= RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex); else value= RNA_property_boolean_get(&but->rnapoin, prop); break; case PROP_INT: - if(RNA_property_array_length(&but->rnapoin, prop)) + if(RNA_property_array_check(prop)) value= RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex); else value= RNA_property_int_get(&but->rnapoin, prop); break; case PROP_FLOAT: - if(RNA_property_array_length(&but->rnapoin, prop)) + if(RNA_property_array_check(prop)) value= RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex); else value= RNA_property_float_get(&but->rnapoin, prop); @@ -1459,19 +1480,20 @@ int ui_get_but_string_max_length(uiBut *but) static double ui_get_but_scale_unit(uiBut *but, double value) { - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); + UnitSettings *unit= but->block->unit; int unit_type= uiButGetUnitType(but); if(unit_type == PROP_UNIT_LENGTH) { - return value * (double)scene->unit.scale_length; + return value * (double)unit->scale_length; } else if(unit_type == PROP_UNIT_AREA) { - return value * pow(scene->unit.scale_length, 2); + return value * pow(unit->scale_length, 2); } else if(unit_type == PROP_UNIT_VOLUME) { - return value * pow(scene->unit.scale_length, 3); + return value * pow(unit->scale_length, 3); } else if(unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */ + Scene *scene= CTX_data_scene(but->block->evil_C); return FRA2TIME(value); } else { @@ -1483,14 +1505,14 @@ static double ui_get_but_scale_unit(uiBut *but, double value) void ui_convert_to_unit_alt_name(uiBut *but, char *str, int maxlen) { if(ui_is_but_unit(but)) { + UnitSettings *unit= but->block->unit; int unit_type= uiButGetUnitType(but); char *orig_str; - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); orig_str= MEM_callocN(sizeof(char)*maxlen + 1, "textedit sub str"); memcpy(orig_str, str, maxlen); - bUnit_ToUnitAltName(str, maxlen, orig_str, scene->unit.system, unit_type>>16); + bUnit_ToUnitAltName(str, maxlen, orig_str, unit->system, unit_type>>16); MEM_freeN(orig_str); } @@ -1498,27 +1520,26 @@ void ui_convert_to_unit_alt_name(uiBut *but, char *str, int maxlen) static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad) { - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); - int do_split= scene->unit.flag & USER_UNIT_OPT_SPLIT; + UnitSettings *unit= but->block->unit; + int do_split= unit->flag & USER_UNIT_OPT_SPLIT; int unit_type= uiButGetUnitType(but); int precision= but->a2; - if(scene->unit.scale_length<0.0001f) scene->unit.scale_length= 1.0f; // XXX do_versions + if(unit->scale_length<0.0001f) unit->scale_length= 1.0f; // XXX do_versions /* Sanity checks */ if(precision > PRECISION_FLOAT_MAX) precision= PRECISION_FLOAT_MAX; else if(precision==0) precision= 2; - bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, scene->unit.system, unit_type>>16, do_split, pad); + bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, unit->system, unit_type>>16, do_split, pad); } static float ui_get_but_step_unit(uiBut *but, float step_default) { - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); int unit_type= uiButGetUnitType(but)>>16; float step; - step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), scene->unit.system, unit_type); + step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), but->block->unit->system, unit_type); if(step > 0.0f) { /* -1 is an error value */ return (float)((double)step/ui_get_but_scale_unit(but, 1.0))*100.0f; @@ -1606,12 +1627,11 @@ static int ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char * { char str_unit_convert[256]; const int unit_type= uiButGetUnitType(but); - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); /* ugly, use the draw string to get the value, this could cause problems if it includes some text which resolves to a unit */ - bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, ui_get_but_scale_unit(but, 1.0), scene->unit.system, unit_type>>16); + bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, ui_get_but_scale_unit(but, 1.0), but->block->unit->system, unit_type>>16); return (BPY_button_exec(C, str_unit_convert, value, TRUE) != -1); } @@ -1958,7 +1978,10 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor block->active= 1; block->dt= dt; block->evil_C= (void*)C; // XXX - if (scn) block->color_profile= (scn->r.color_mgt_flag & R_COLOR_MANAGEMENT); + if (scn) { + block->color_profile= (scn->r.color_mgt_flag & R_COLOR_MANAGEMENT); + block->unit= &scn->unit; + } BLI_strncpy(block->name, name, sizeof(block->name)); if(region) @@ -2490,138 +2513,139 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, return but; } -static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) +/* ui_def_but_rna_propname and ui_def_but_rna + * both take the same args except for propname vs prop, this is done so we can + * avoid an extra lookup on 'prop' when its already available. + * + * When this kind of change won't disrupt branches, best look into making more + * of our UI functions take prop rather then propname. + */ + +#define UI_DEF_BUT_RNA_DISABLE(but) \ + but->flag |= UI_BUT_DISABLED; \ + but->lock = 1; \ + but->lockstr = "" + + +static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { + const PropertyType proptype= RNA_property_type(prop); uiBut *but; - PropertyRNA *prop; - PropertyType proptype; int freestr= 0, icon= 0; - prop= RNA_struct_find_property(ptr, propname); - - if(prop) { - proptype= RNA_property_type(prop); - - /* use rna values if parameters are not specified */ - if(!str) { - if(type == MENU && proptype == PROP_ENUM) { - EnumPropertyItem *item; - DynStr *dynstr; - int i, totitem, value, free; - - RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); - value= RNA_property_enum_get(ptr, prop); - - dynstr= BLI_dynstr_new(); - BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop)); - for(i=0; i<totitem; i++) { - if(!item[i].identifier[0]) { - if(item[i].name) - BLI_dynstr_appendf(dynstr, "|%s%%l", item[i].name); - else - BLI_dynstr_append(dynstr, "|%l"); - } - else if(item[i].icon) - BLI_dynstr_appendf(dynstr, "|%s %%i%d %%x%d", item[i].name, item[i].icon, item[i].value); + /* use rna values if parameters are not specified */ + if(!str) { + if(type == MENU && proptype == PROP_ENUM) { + EnumPropertyItem *item; + DynStr *dynstr; + int i, totitem, value, free; + + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); + value= RNA_property_enum_get(ptr, prop); + + dynstr= BLI_dynstr_new(); + BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop)); + for(i=0; i<totitem; i++) { + if(!item[i].identifier[0]) { + if(item[i].name) + BLI_dynstr_appendf(dynstr, "|%s%%l", item[i].name); else - BLI_dynstr_appendf(dynstr, "|%s %%x%d", item[i].name, item[i].value); + BLI_dynstr_append(dynstr, "|%l"); + } + else if(item[i].icon) + BLI_dynstr_appendf(dynstr, "|%s %%i%d %%x%d", item[i].name, item[i].icon, item[i].value); + else + BLI_dynstr_appendf(dynstr, "|%s %%x%d", item[i].name, item[i].value); - if(value == item[i].value) { - icon= item[i].icon; - if(!tip) - tip= item[i].description; - } + if(value == item[i].value) { + icon= item[i].icon; + if(!tip) + tip= item[i].description; } - str= BLI_dynstr_get_cstring(dynstr); - BLI_dynstr_free(dynstr); + } + str= BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); - if(free) - MEM_freeN(item); + if(free) + MEM_freeN(item); - freestr= 1; - } - else if(ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) { - EnumPropertyItem *item; - int i, totitem, free; - - RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); - for(i=0; i<totitem; i++) { - if(item[i].identifier[0] && item[i].value == (int)max) { - str= item[i].name; - icon= item[i].icon; - } - } + freestr= 1; + } + else if(ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) { + EnumPropertyItem *item; + int i, totitem, free; - if(!str) - str= RNA_property_ui_name(prop); - if(free) - MEM_freeN(item); + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); + for(i=0; i<totitem; i++) { + if(item[i].identifier[0] && item[i].value == (int)max) { + str= item[i].name; + icon= item[i].icon; + } } - else { + + if(!str) str= RNA_property_ui_name(prop); - icon= RNA_property_ui_icon(prop); - } + if(free) + MEM_freeN(item); } - - if(!tip && proptype != PROP_ENUM) - tip= RNA_property_ui_description(prop); + else { + str= RNA_property_ui_name(prop); + icon= RNA_property_ui_icon(prop); + } + } - if(min == max || a1 == -1 || a2 == -1) { - if(proptype == PROP_INT) { - int hardmin, hardmax, softmin, softmax, step; + if(!tip && proptype != PROP_ENUM) + tip= RNA_property_ui_description(prop); - RNA_property_int_range(ptr, prop, &hardmin, &hardmax); - RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); + if(min == max || a1 == -1 || a2 == -1) { + if(proptype == PROP_INT) { + int hardmin, hardmax, softmin, softmax, step; - if(!ELEM(type, ROW, LISTROW) && min == max) { - min= hardmin; - max= hardmax; - } - if(a1 == -1) - a1= step; - if(a2 == -1) - a2= 0; + RNA_property_int_range(ptr, prop, &hardmin, &hardmax); + RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); + + if(!ELEM(type, ROW, LISTROW) && min == max) { + min= hardmin; + max= hardmax; } - else if(proptype == PROP_FLOAT) { - float hardmin, hardmax, softmin, softmax, step, precision; + if(a1 == -1) + a1= step; + if(a2 == -1) + a2= 0; + } + else if(proptype == PROP_FLOAT) { + float hardmin, hardmax, softmin, softmax, step, precision; - RNA_property_float_range(ptr, prop, &hardmin, &hardmax); - RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); + RNA_property_float_range(ptr, prop, &hardmin, &hardmax); + RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); - if(!ELEM(type, ROW, LISTROW) && min == max) { - min= hardmin; - max= hardmax; - } - if(a1 == -1) - a1= step; - if(a2 == -1) - a2= precision; - } - else if(proptype == PROP_STRING) { - min= 0; - max= RNA_property_string_maxlength(prop); - if(max == 0) /* interface code should ideally support unlimited length */ - max= UI_MAX_DRAW_STR; + if(!ELEM(type, ROW, LISTROW) && min == max) { + min= hardmin; + max= hardmax; } + if(a1 == -1) + a1= step; + if(a2 == -1) + a2= precision; + } + else if(proptype == PROP_STRING) { + min= 0; + max= RNA_property_string_maxlength(prop); + if(max == 0) /* interface code should ideally support unlimited length */ + max= UI_MAX_DRAW_STR; } - } - else { - RNA_warning("ui_def_but_rna: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); - str= propname; } /* now create button */ but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, NULL, min, max, a1, a2, tip); - if(prop) { - but->rnapoin= *ptr; - but->rnaprop= prop; + but->rnapoin= *ptr; + but->rnaprop= prop; - if(RNA_property_array_length(&but->rnapoin, but->rnaprop)) - but->rnaindex= index; - else - but->rnaindex= 0; - } + if(RNA_property_array_length(&but->rnapoin, but->rnaprop)) + but->rnaindex= index; + else + but->rnaindex= 0; if(icon) { but->icon= (BIFIconID)icon; @@ -2629,15 +2653,18 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s but->flag|= UI_ICON_LEFT; } - if (!prop || !RNA_property_editable(&but->rnapoin, prop)) { - but->flag |= UI_BUT_DISABLED; - but->lock = 1; - but->lockstr = ""; + if (!RNA_property_editable(&but->rnapoin, prop)) { + UI_DEF_BUT_RNA_DISABLE(but); + } + + if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == FALSE)) { + but->flag &= ~UI_BUT_UNDO; } /* If this button uses units, calculate the step from this */ - if(ui_is_but_unit(but)) + if((proptype == PROP_FLOAT) && ui_is_but_unit(but)) { but->a1= ui_get_but_step_unit(but, but->a1); + } if(freestr) MEM_freeN((void *)str); @@ -2645,6 +2672,23 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s return but; } +static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, propname); + uiBut *but; + + if(prop) { + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + } + else { + but= ui_def_but(block, type, retval, propname, x1, y1, x2, y2, NULL, min, max, a1, a2, tip); + + UI_DEF_BUT_RNA_DISABLE(but); + } + + return but; +} + static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; @@ -2664,6 +2708,7 @@ static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, but= ui_def_but(block, type, -1, str, x1, y1, x2, y2, NULL, 0, 0, 0, 0, tip); but->optype= ot; but->opcontext= opcontext; + but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_undo(), we never need undo here */ if(!ot) { but->flag |= UI_BUT_DISABLED; @@ -2693,6 +2738,7 @@ static uiBut *ui_def_but_operator_text(uiBlock *block, int type, const char *opn but= ui_def_but(block, type, -1, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); but->optype= ot; but->opcontext= opcontext; + but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_undo(), we never need undo here */ if(!ot) { but->flag |= UI_BUT_DISABLED; @@ -2812,6 +2858,16 @@ static void autocomplete_id(bContext *C, char *str, void *arg_v) } } +static void ui_check_but_and_iconize(uiBut *but, int icon) +{ + if(icon) { + but->icon= (BIFIconID) icon; + but->flag|= UI_HAS_ICON; + } + + ui_check_but(but); +} + static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { int bitIdx= findBitIndex(bit); @@ -2856,31 +2912,29 @@ uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *s uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - - but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) - ui_check_but(but); - + but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + ui_check_but(but); + return but; +} +uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but(but); return but; } uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); - if(but) - ui_check_but(but); - + ui_check_but(but); return but; } uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but_operator_text(block, type, opname, opcontext, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - if(but) - ui_check_but(but); - + ui_check_but(but); return but; } @@ -2888,12 +2942,7 @@ uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but(block, type, retval, "", x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - - ui_check_but(but); - + ui_check_but_and_iconize(but, icon); return but; } static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -2941,29 +2990,22 @@ uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - - but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) { - if(icon) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - } - ui_check_but(but); - } - + but= ui_def_but_rna_propname(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); + return but; +} +uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); return but; } uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, "", x1, y1, x2, y2, tip); - if(but) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); return but; } @@ -2971,14 +3013,8 @@ uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip); - - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - + ui_check_but_and_iconize(but, icon); but->flag|= UI_ICON_LEFT; - - ui_check_but(but); - return but; } static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3026,31 +3062,25 @@ uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int i uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) { uiBut *but; - - but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); - if(but) { - if(icon) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - } - but->flag|= UI_ICON_LEFT; - ui_check_but(but); - } - + but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; + return but; +} +uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) +{ + uiBut *but; + but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip); + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; return but; } uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip) { uiBut *but; - but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip); - if(but) { - but->icon= (BIFIconID) icon; - but->flag|= UI_HAS_ICON; - but->flag|= UI_ICON_LEFT; - ui_check_but(but); - } - + ui_check_but_and_iconize(but, icon); + but->flag|= UI_ICON_LEFT; return but; } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 97299a6a766..dd7d2ca765f 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -140,26 +140,25 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r glEnd(); } -static void round_box_shade_col(float *col1, float *col2, float fac) +static void round_box_shade_col(const float col1[3], float const col2[3], const float fac) { - float col[4]; + float col[3]; col[0]= (fac*col1[0] + (1.0f-fac)*col2[0]); col[1]= (fac*col1[1] + (1.0f-fac)*col2[1]); col[2]= (fac*col1[2] + (1.0f-fac)*col2[2]); - col[3]= (fac*col1[3] + (1.0f-fac)*col2[3]); - glColor4fv(col); + glColor3fv(col); } - /* linear horizontal shade within button or in outline */ /* view2d scrollers use it */ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown) { float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; - float div= maxy-miny; - float coltop[4], coldown[4], color[4]; + const float div= maxy - miny; + const float idiv= 1.0f / div; + float coltop[3], coldown[3], color[4]; int a; /* mult */ @@ -173,11 +172,9 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl coltop[0]= color[0]+shadetop; if(coltop[0]>1.0f) coltop[0]= 1.0f; coltop[1]= color[1]+shadetop; if(coltop[1]>1.0f) coltop[1]= 1.0f; coltop[2]= color[2]+shadetop; if(coltop[2]>1.0f) coltop[2]= 1.0f; - coltop[3]= color[3]; coldown[0]= color[0]+shadedown; if(coldown[0]<0.0f) coldown[0]= 0.0f; coldown[1]= color[1]+shadedown; if(coldown[1]<0.0f) coldown[1]= 0.0f; coldown[2]= color[2]+shadedown; if(coldown[2]<0.0f) coldown[2]= 0.0f; - coldown[3]= color[3]; glShadeModel(GL_SMOOTH); glBegin(mode); @@ -189,11 +186,11 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl glVertex2f(maxx-rad, miny); for(a=0; a<7; a++) { - round_box_shade_col(coltop, coldown, vec[a][1]/div); + round_box_shade_col(coltop, coldown, vec[a][1]*idiv); glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]); } - round_box_shade_col(coltop, coldown, rad/div); + round_box_shade_col(coltop, coldown, rad*idiv); glVertex2f(maxx, miny+rad); } else { @@ -204,11 +201,11 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl /* corner right-top */ if(roundboxtype & 2) { - round_box_shade_col(coltop, coldown, (div-rad)/div); + round_box_shade_col(coltop, coldown, (div-rad)*idiv); glVertex2f(maxx, maxy-rad); for(a=0; a<7; a++) { - round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div); + round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])*idiv); glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]); } round_box_shade_col(coltop, coldown, 1.0); @@ -226,11 +223,11 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl glVertex2f(minx+rad, maxy); for(a=0; a<7; a++) { - round_box_shade_col(coltop, coldown, (div-vec[a][1])/div); + round_box_shade_col(coltop, coldown, (div-vec[a][1])*idiv); glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]); } - round_box_shade_col(coltop, coldown, (div-rad)/div); + round_box_shade_col(coltop, coldown, (div-rad)*idiv); glVertex2f(minx, maxy-rad); } else { @@ -241,11 +238,11 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl /* corner left-bottom */ if(roundboxtype & 8) { - round_box_shade_col(coltop, coldown, rad/div); + round_box_shade_col(coltop, coldown, rad*idiv); glVertex2f(minx, miny+rad); for(a=0; a<7; a++) { - round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div); + round_box_shade_col(coltop, coldown, (rad-vec[a][1])*idiv); glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]); } @@ -267,7 +264,8 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float { float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; - float div= maxx-minx; + const float div= maxx - minx; + const float idiv= 1.0f / div; float colLeft[3], colRight[3], color[4]; int a; @@ -295,11 +293,11 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float glVertex2f(maxx-rad, miny); for(a=0; a<7; a++) { - round_box_shade_col(colLeft, colRight, vec[a][0]/div); + round_box_shade_col(colLeft, colRight, vec[a][0]*idiv); glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]); } - round_box_shade_col(colLeft, colRight, rad/div); + round_box_shade_col(colLeft, colRight, rad*idiv); glVertex2f(maxx, miny+rad); } else { @@ -314,10 +312,10 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float for(a=0; a<7; a++) { - round_box_shade_col(colLeft, colRight, (div-rad-vec[a][0])/div); + round_box_shade_col(colLeft, colRight, (div-rad-vec[a][0])*idiv); glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]); } - round_box_shade_col(colLeft, colRight, (div-rad)/div); + round_box_shade_col(colLeft, colRight, (div-rad)*idiv); glVertex2f(maxx-rad, maxy); } else { @@ -327,11 +325,11 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float /* corner left-top */ if(roundboxtype & 1) { - round_box_shade_col(colLeft, colRight, (div-rad)/div); + round_box_shade_col(colLeft, colRight, (div-rad)*idiv); glVertex2f(minx+rad, maxy); for(a=0; a<7; a++) { - round_box_shade_col(colLeft, colRight, (div-rad+vec[a][0])/div); + round_box_shade_col(colLeft, colRight, (div-rad+vec[a][0])*idiv); glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]); } @@ -349,7 +347,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float glVertex2f(minx, miny+rad); for(a=0; a<7; a++) { - round_box_shade_col(colLeft, colRight, (vec[a][0])/div); + round_box_shade_col(colLeft, colRight, (vec[a][0])*idiv); glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c5275ea98b5..3bd29f8de3e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1290,7 +1290,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho else if(ELEM(but->type, TEX, SEARCH_MENU)) { startx += 5; if (but->flag & UI_HAS_ICON) - startx += 16; + startx += UI_DPI_ICON_SIZE; } /* mouse dragged outside the widget to the left */ @@ -2310,13 +2310,13 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa float fac= 1.0f; if(ui_is_but_unit(but)) { - Scene *scene= CTX_data_scene((bContext *)but->block->evil_C); + UnitSettings *unit= but->block->unit; int unit_type= uiButGetUnitType(but)>>16; - if(bUnit_IsValid(scene->unit.system, unit_type)) { - fac= (float)bUnit_BaseScalar(scene->unit.system, unit_type); + if(bUnit_IsValid(unit->system, unit_type)) { + fac= (float)bUnit_BaseScalar(unit->system, unit_type); if(ELEM3(unit_type, B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME)) { - fac /= scene->unit.scale_length; + fac /= unit->scale_length; } } } @@ -2856,7 +2856,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { - int mx, my, click= 0; + int mx, my /*, click= 0 */; int retval= WM_UI_HANDLER_CONTINUE; int horizontal= (but->x2 - but->x1 > but->y2 - but->y1); @@ -2878,8 +2878,10 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval= WM_UI_HANDLER_BREAK; } - else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS) + /* UNUSED - otherwise code is ok, add back if needed */ + /* else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS) click= 1; + */ } } else if(data->state == BUTTON_STATE_NUM_EDITING) { @@ -3677,6 +3679,9 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt return WM_UI_HANDLER_BREAK; } + /* UNUSED but keep for now */ + (void)changed; + return WM_UI_HANDLER_CONTINUE; } @@ -3691,12 +3696,12 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx Histogram *hist = (Histogram *)but->poin; /* rcti rect; */ int changed= 1; - float dx, dy, yfac=1.f; + float /* dx, */ dy, yfac=1.f; /* UNUSED */ /* rect.xmin= but->x1; rect.xmax= but->x2; */ /* rect.ymin= but->y1; rect.ymax= but->y2; */ - dx = mx - data->draglastx; + /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; @@ -3774,12 +3779,12 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, Scopes *scopes = (Scopes *)but->poin; /* rcti rect; */ int changed= 1; - float dx, dy, yfac=1.f; + float /* dx, */ dy /* , yfac=1.f */; /* UNUSED */ /* rect.xmin= but->x1; rect.xmax= but->x2; */ /* rect.ymin= but->y1; rect.ymax= but->y2; */ - dx = mx - data->draglastx; + /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; @@ -3788,7 +3793,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, scopes->wavefrm_height = (but->y2 - but->y1) + (data->dragstarty - my); } else { /* scale waveform values */ - yfac = scopes->wavefrm_yfac; + /* yfac = scopes->wavefrm_yfac; */ /* UNUSED */ scopes->wavefrm_yfac += dy/200.0f; CLAMP(scopes->wavefrm_yfac, 0.5f, 2.f); @@ -4067,7 +4072,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) /* complex code to change name of button */ if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) { - wmKeyMap *km= NULL; char *butstr_orig; // XXX but->str changed... should not, remove the hotkey from it @@ -4080,10 +4084,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) but->str= but->strdata; ui_check_but(but); - - /* set the keymap editable else the key wont save */ - WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km); - WM_keymap_copy_to_user(km); } else { /* shortcut was removed */ @@ -4095,6 +4095,7 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) { + wmWindowManager *wm= CTX_wm_manager(C); uiBlock *block; uiBut *but = (uiBut *)arg; wmKeyMap *km; @@ -4107,7 +4108,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) kmi = WM_keymap_item_find_id(km, kmi_id); - RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr); + RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); uiBlockSetHandleFunc(block, but_shortcut_name_func, but); @@ -4126,6 +4127,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) { + wmWindowManager *wm= CTX_wm_manager(C); uiBlock *block; uiBut *but = (uiBut *)arg; wmKeyMap *km; @@ -4134,19 +4136,25 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) uiLayout *layout; uiStyle *style= U.uistyles.first; IDProperty *prop= (but->opptr)? but->opptr->data: NULL; + int kmi_id; /* XXX this guess_opname can potentially return a different keymap than being found on adding later... */ km = WM_keymap_guess_opname(C, but->optype->idname); kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0); + kmi_id = kmi->id; - if (prop) { + /* copy properties, prop can be NULL for reset */ + if(prop) prop= IDP_CopyProperty(prop); - } - - /* prop can be NULL */ WM_keymap_properties_reset(kmi, prop); - RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr); + /* update and get pointers again */ + WM_keyconfig_update(wm); + + km = WM_keymap_guess_opname(C, but->optype->idname); + kmi = WM_keymap_item_find_id(km, kmi_id); + + RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr); block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); uiBlockSetHandleFunc(block, but_shortcut_name_func, but); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3bf2a9ddd02..412c0233c35 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -742,6 +742,7 @@ static DrawInfo *icon_create_drawinfo(void) return di; } +/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */ int UI_icon_get_width(int icon_id) { Icon *icon = NULL; @@ -952,7 +953,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al Icon *icon = NULL; DrawInfo *di = NULL; IconImage *iimg; - float fdraw_size= UI_DPI_FAC*draw_size; + float fdraw_size= UI_DPI_ICON_FAC*draw_size; int w, h; icon = BKE_icon_get(icon_id); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 8475090b468..40b98bebcd0 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -213,7 +213,7 @@ struct uiBut { BIFIconID icon; char lock; - char dt; + char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied from the block */ char changed; /* could be made into a single flag */ unsigned char unit_type; /* so buttons can support unit systems which are not RNA */ short modifier_key; @@ -306,7 +306,8 @@ struct uiBlock { void *drawextra_arg2; int flag; - char direction, dt; + char direction; + char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied to buttons */ short auto_open; double auto_open_last; @@ -331,7 +332,9 @@ struct uiBlock { void *evil_C; // XXX hack for dynamic operator enums float _hsv[3]; // XXX, only access via ui_block_hsv_get() - char color_profile; // color profile for correcting linear colors for display + char color_profile; // color profile for correcting linear colors for display + struct UnitSettings *unit; // unit system, used a lot for numeric buttons so include here rather then fetching through the scene every time. + }; typedef struct uiSafetyRct { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2f0bcc9d5b4..3575a8527fc 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -367,7 +367,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in unit= UI_UNIT_X*0.75; butw= unit; buth= unit; - + if(ptr->type == &RNA_Armature) { bArmature *arm= (bArmature *)ptr->data; layer_used= arm->layer_used; @@ -379,7 +379,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in for(a=0; a<colbuts; a++) { if(layer_used & (1<<(a+b*colbuts))) icon= ICON_LAYER_USED; else icon= ICON_BLANK1; - + but= uiDefAutoButR(block, ptr, prop, a+b*colbuts, "", icon, x + butw*a, y+buth, butw, buth); if(subtype == PROP_LAYER_MEMBER) uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(a+b*colbuts)); @@ -387,7 +387,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in for(a=0; a<colbuts; a++) { if(layer_used & (1<<(a+len/2+b*colbuts))) icon= ICON_LAYER_USED; else icon= ICON_BLANK1; - + but= uiDefAutoButR(block, ptr, prop, a+len/2+b*colbuts, "", icon, x + butw*a, y, butw, buth); if(subtype == PROP_LAYER_MEMBER) uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(a+len/2+b*colbuts)); @@ -419,38 +419,49 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in } } else if(subtype == PROP_DIRECTION) { - uiDefButR(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, prop, 0, 0, 0, -1, -1, NULL); } else { - if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand) + /* note, this block of code is a bit arbitrary and has just been made + * to work with common cases, but may need to be re-worked */ + + /* special case, boolean array in a menu, this could be used in a more generic way too */ + if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand) { uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y); + } + else { + int *boolarr= NULL; - if(!ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) || expand) { - /* layout for known array subtypes */ - char str[3]; + /* even if 'expand' is fale, expanding anyway */ - for(a=0; a<len; a++) { - str[0]= RNA_property_array_item_char(prop, a); + /* layout for known array subtypes */ + char str[3]= {'\0'}; - if(str[0]) { - if (icon_only) { - str[0] = '\0'; - } - else if(type == PROP_BOOLEAN) { - str[1]= '\0'; - } - else { - str[1]= ':'; - str[2]= '\0'; - } + if(!icon_only) { + if(type != PROP_BOOLEAN) { + str[1]= ':'; } + } + + /* show checkboxes for rna on a non-emboss block (menu for eg) */ + if(type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSSN, UI_EMBOSSP)) { + boolarr= MEM_callocN(sizeof(int)*len, "ui_item_array"); + RNA_property_boolean_get_array(ptr, prop, boolarr); + } + for(a=0; a<len; a++) { + if(!icon_only) str[0]= RNA_property_array_item_char(prop, a); + if(boolarr) icon= boolarr[a] ? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; but= uiDefAutoButR(block, ptr, prop, a, str, icon, 0, 0, w, UI_UNIT_Y); if(slider && but->type==NUM) but->type= NUMSLI; if(toggle && but->type==OPTION) but->type= TOG; } + + if(boolarr) { + MEM_freeN(boolarr); + } } } @@ -461,11 +472,9 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt { uiBut *but; EnumPropertyItem *item; - const char *identifier; const char *name; int a, totitem, itemw, icon, value, free; - identifier= RNA_property_identifier(prop); RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1)); @@ -479,11 +488,11 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt itemw= ui_text_icon_width(block->curlayout, name, icon, 0); if(icon && name[0] && !icon_only) - but= uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if(icon) - but= uiDefIconButR(block, ROW, 0, icon, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); else - but= uiDefButR(block, ROW, 0, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + but= uiDefButR_prop(block, ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); if(ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL) but->flag |= UI_TEXT_LEFT; @@ -540,7 +549,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if(flag & UI_ITEM_R_EVENT) { - uiDefButR(block, KEYEVT, 0, name, x, y, w, h, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL); + uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); } else if(flag & UI_ITEM_R_FULL_EVENT) { if(RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) { @@ -548,7 +557,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n WM_keymap_item_to_string(ptr->data, buf, sizeof(buf)); - but= uiDefButR(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, ui_keymap_but_cb, but, NULL); if (flag & UI_ITEM_R_IMMEDIATE) uiButSetFlag(but, UI_BUT_IMMEDIATE); @@ -953,13 +962,14 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index uiBut *but; PropertyType type; char namestr[UI_MAX_NAME_STR]; - int len, w, h, slider, toggle, expand, icon_only, no_bg; + int len, is_array, w, h, slider, toggle, expand, icon_only, no_bg; uiBlockSetCurLayout(block, layout); /* retrieve info */ type= RNA_property_type(prop); - len= RNA_property_array_length(ptr, prop); + is_array= RNA_property_array_check(prop); + len= (is_array) ? RNA_property_array_length(ptr, prop) : 0; /* set name and icon */ if(!name) @@ -969,14 +979,16 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index if(ELEM4(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER)) name= ui_item_name_add_colon(name, namestr); - else if(type == PROP_BOOLEAN && len && index == RNA_NO_INDEX) + else if(type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX) name= ui_item_name_add_colon(name, namestr); else if(type == PROP_ENUM && index != RNA_ENUM_VALUE) name= ui_item_name_add_colon(name, namestr); if(layout->root->type == UI_LAYOUT_MENU) { - if(type == PROP_BOOLEAN) - icon= (RNA_property_boolean_get(ptr, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + if(type == PROP_BOOLEAN && ((is_array == FALSE) || (index != RNA_NO_INDEX))) { + if(is_array) icon= (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + else icon= (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; + } else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) { int enum_value= RNA_property_enum_get(ptr, prop); if(RNA_property_flag(prop) & PROP_ENUM_FLAG) { @@ -1001,18 +1013,16 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index uiBlockSetEmboss(block, UI_EMBOSSN); /* array property */ - if(index == RNA_NO_INDEX && len > 0) + if(index == RNA_NO_INDEX && is_array) ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand, slider, toggle, icon_only); /* enum item */ else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) { - const char *identifier= RNA_property_identifier(prop); - if(icon && name[0] && !icon_only) - uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); else if(icon) - uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); else - uiDefButR(block, ROW, 0, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL); + uiDefButR_prop(block, ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL); } /* expanded enum */ else if(type == PROP_ENUM && (expand || RNA_property_flag(prop) & PROP_ENUM_FLAG)) @@ -2747,6 +2757,25 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,in uiItemL(layout, "* Redo Unsupported *", ICON_NONE); // XXX, could give some nicer feedback or not show redo panel at all? } + /* menu */ + if(op->type->flag & OPTYPE_PRESET) { + /* XXX, no simple way to get WM_MT_operator_presets.bl_label from python! Label remains the same always! */ + PointerRNA op_ptr; + uiLayout *row; + + row= uiLayoutRow(layout, TRUE); + uiItemM(row, (bContext *)C, "WM_MT_operator_presets", NULL, ICON_NONE); + + WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); + RNA_string_set(&op_ptr, "operator", op->type->idname); + op_ptr= uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMIN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + + WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); + RNA_string_set(&op_ptr, "operator", op->type->idname); + RNA_boolean_set(&op_ptr, "remove_active", 1); + op_ptr= uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMOUT, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + } + if(op->type->ui) { op->layout= layout; op->type->ui((bContext*)C, op); @@ -2761,25 +2790,6 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,in RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - /* menu */ - if(op->type->flag & OPTYPE_PRESET) { - /* XXX, no simple way to get WM_MT_operator_presets.bl_label from python! Label remains the same always! */ - PointerRNA op_ptr; - uiLayout *row; - - row= uiLayoutRow(layout, TRUE); - uiItemM(row, (bContext *)C, "WM_MT_operator_presets", NULL, ICON_NONE); - - WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); - RNA_string_set(&op_ptr, "operator", op->type->idname); - op_ptr= uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMIN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); - - WM_operator_properties_create(&op_ptr, "WM_OT_operator_preset_add"); - RNA_string_set(&op_ptr, "operator", op->type->idname); - RNA_boolean_set(&op_ptr, "remove_active", 1); - op_ptr= uiItemFullO(row, "WM_OT_operator_preset_add", "", ICON_ZOOMOUT, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); - } - /* main draw call */ empty= uiDefAutoButsRNA(layout, &ptr, check_prop, label_align) == 0; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9e7717260e6..a55ee01202c 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -424,7 +424,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if (unit_type == PROP_UNIT_ROTATION) { if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Radians: %f", RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex)); + float value= RNA_property_array_check(but->rnaprop) ? RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) : RNA_property_float_get(&but->rnapoin, but->rnaprop); + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Radians: %f", value); data->color[data->totline]= 0x888888; data->totline++; } @@ -1188,7 +1189,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, uiBut *bt; uiSafetyRct *saferct; rctf butrct; - float aspect; + /*float aspect;*/ /*UNUSED*/ int xsize, ysize, xof=0, yof=0, center; short dir1= 0, dir2=0; @@ -1223,7 +1224,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, } } - aspect= (float)(block->maxx - block->minx + 4); + /*aspect= (float)(block->maxx - block->minx + 4);*/ /*UNUSED*/ ui_block_to_window_fl(butregion, but->block, &block->minx, &block->miny); ui_block_to_window_fl(butregion, but->block, &block->maxx, &block->maxy); @@ -1232,7 +1233,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, xsize= block->maxx - block->minx+4; // 4 for shadow ysize= block->maxy - block->miny+4; - aspect/= (float)xsize; + /*aspect/= (float)xsize;*/ /*UNUSED*/ if(but) { int left=0, right=0, top=0, down=0; @@ -1934,31 +1935,31 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a #define PICKER_TOTAL_W (PICKER_W+PICKER_SPACE+PICKER_BAR) -static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname) +static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop) { uiBut *bt; /* HS circle */ - bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "Color"); + bt= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } -static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname, int type) +static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type) { uiBut *bt; int bartype = type + 3; /* HS square */ - bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "Color"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt= uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "Value"); + bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } @@ -1973,7 +1974,6 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR static char hexcol[128]; float rgb_gamma[3]; float min, max, step, precision; - const char *propname = RNA_property_identifier(prop); float *hsv= ui_block_hsv_get(block); ui_block_hsv_get(block); @@ -1999,16 +1999,16 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR switch (U.color_picker_type) { case USER_CP_CIRCLE: - circle_picker(block, ptr, propname); + circle_picker(block, ptr, prop); break; case USER_CP_SQUARE_SV: - square_picker(block, ptr, propname, UI_GRAD_SV); + square_picker(block, ptr, prop, UI_GRAD_SV); break; case USER_CP_SQUARE_HS: - square_picker(block, ptr, propname, UI_GRAD_HS); + square_picker(block, ptr, prop, UI_GRAD_HS); break; case USER_CP_SQUARE_HV: - square_picker(block, ptr, propname, UI_GRAD_HV); + square_picker(block, ptr, prop, UI_GRAD_HV); break; } @@ -2027,11 +2027,11 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR /* RGB values */ uiBlockBeginAlign(block); - bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "Red"); + bt= uiDefButR_prop(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, "Red"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "Green"); + bt= uiDefButR_prop(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, "Green"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "Blue"); + bt= uiDefButR_prop(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, "Blue"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); // could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); @@ -2048,7 +2048,7 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR uiBlockEndAlign(block); if(rgb[3] != FLT_MAX) { - bt= uiDefButR(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "Alpha"); + bt= uiDefButR_prop(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, "Alpha"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } else { diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 5f2a757d2e3..8d4b4209120 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -149,9 +149,9 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, int xofs=0, yofs; uiStyleFontSet(fs); - - height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */ - yofs= floor( 0.5f*(rect->ymax - rect->ymin - height)); + + height= BLF_ascender(fs->uifont_id); + yofs= ceil( 0.5f*(rect->ymax - rect->ymin - height)); if(fs->align==UI_STYLE_TEXT_CENTER) { xofs= floor( 0.5f*(rect->xmax - rect->xmin - BLF_width(fs->uifont_id, str))); @@ -206,9 +206,9 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str) uiStyleFontSet(fs); - height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */ + height= BLF_ascender(fs->uifont_id); /* becomes x-offset when rotated */ - xofs= floor( 0.5f*(rect->ymax - rect->ymin - height)) + 1; + xofs= ceil( 0.5f*(rect->ymax - rect->ymin - height)); /* ignore UI_STYLE, always aligned to top */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index cadcf959ace..fcca3ec7aec 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -40,6 +40,7 @@ #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BKE_animsys.h" #include "BKE_colortools.h" @@ -55,6 +56,7 @@ #include "BKE_displist.h" #include "ED_screen.h" +#include "ED_object.h" #include "ED_render.h" #include "RNA_access.h" @@ -277,18 +279,28 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) break; case UI_ID_ALONE: if(id) { + const int do_scene_obj= (GS(id->name) == ID_OB) && + (template->ptr.type == &RNA_SceneObjects); + /* make copy */ - if(id_copy(id, &newid, 0) && newid) { - /* copy animation actions too */ - BKE_copy_animdata_id_action(id); - /* us is 1 by convention, but RNA_property_pointer_set - will also incremement it, so set it to zero */ - newid->us= 0; - - /* assign copy */ - RNA_id_pointer_create(newid, &idptr); - RNA_property_pointer_set(&template->ptr, template->prop, idptr); - RNA_property_update(C, &template->ptr, template->prop); + if(do_scene_obj) { + Scene *scene= CTX_data_scene(C); + ED_object_single_user(scene, (struct Object *)id); + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); + } + else { + if(id_copy(id, &newid, 0) && newid) { + /* copy animation actions too */ + BKE_copy_animdata_id_action(id); + /* us is 1 by convention, but RNA_property_pointer_set + will also incremement it, so set it to zero */ + newid->us= 0; + + /* assign copy */ + RNA_id_pointer_create(newid, &idptr); + RNA_property_pointer_set(&template->ptr, template->prop, idptr); + RNA_property_update(C, &template->ptr, template->prop); + } } } break; @@ -406,10 +418,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str sprintf(str, "%d", id->us); - if(id->us<10) - but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); - else - but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X+10,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); + but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X + ((id->us < 10) ? 0:10), UI_UNIT_Y, NULL, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy."); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE)); if(!id_copy(id, NULL, 1 /* test only */) || (idfrom && idfrom->lib) || !editable) @@ -1886,7 +1895,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam col = uiLayoutColumn(layout, 0); row= uiLayoutRow(col, 1); - but= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, ""); + but= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, 0, 0, ""); if(lock) { but->flag |= UI_BUT_COLOR_LOCK; @@ -1905,7 +1914,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam uiItemS(row); if (value_slider) - uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); + uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, prop, -1, softmin, softmax, UI_GRAD_V_ALT, 0, ""); } /********************* Layer Buttons Template ************************/ @@ -2043,7 +2052,7 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int return rnaicon; } -static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, const char *activepropname) +static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop) { uiBlock *block= uiLayoutGetBlock(layout); uiBut *but; @@ -2057,7 +2066,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe /* list item behind label & other buttons */ sub= uiLayoutRow(overlap, 0); - but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, ""); + but= uiDefButR_prop(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, ""); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); sub= uiLayoutRow(overlap, 0); @@ -2111,7 +2120,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe } else if(itemptr->type == &RNA_ShapeKey) { Object *ob= (Object*)activeptr->data; - Key *key= (Key*)itemptr->data; + Key *key= (Key*)itemptr->id.data; split= uiLayoutSplit(sub, 0.75f, 0); @@ -2228,7 +2237,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * row= uiLayoutRow(col, 0); icon= list_item_icon_get(C, &itemptr, rnaicon, 1); - but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, ""); + but= uiDefIconButR_prop(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, ""); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); @@ -2268,7 +2277,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * /* next/prev button */ sprintf(str, "%d :", i); - but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, ""); + but= uiDefIconTextButR_prop(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, ""); if(i == 0) uiButSetFlag(but, UI_BUT_DISABLED); } @@ -2307,7 +2316,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char * /* create list items */ RNA_PROP_BEGIN(ptr, itemptr, prop) { if(i >= pa->list_scroll && i<pa->list_scroll+items) - list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activepropname); + list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activeprop); i++; } @@ -2341,10 +2350,11 @@ static void operator_call_cb(bContext *C, void *UNUSED(arg1), void *arg2) static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { - wmOperatorType *ot = WM_operatortype_first(); - - for(; ot; ot= ot->next) { - + GHashIterator *iter= WM_operatortype_iter(); + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + wmOperatorType *ot= BLI_ghashIterator_getValue(iter); + if(BLI_strcasestr(ot->name, str)) { if(WM_operator_poll((bContext*)C, ot)) { char name[256]; @@ -2364,6 +2374,7 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char } } } + BLI_ghashIterator_free(iter); } void uiTemplateOperatorSearch(uiLayout *layout) diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 1ec125c2f26..a3f56192cb5 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -51,56 +51,53 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2) { uiBut *but=NULL; - const char *propname= RNA_property_identifier(prop); - char prop_item[MAX_IDPROP_NAME+4]; /* size of the ID prop name + room for [""] */ - int arraylen= RNA_property_array_length(ptr, prop); - - /* support for custom props */ - if(RNA_property_is_idprop(prop)) { - sprintf(prop_item, "[\"%s\"]", propname); - propname= prop_item; - } switch(RNA_property_type(prop)) { - case PROP_BOOLEAN: { + case PROP_BOOLEAN: + { + int arraylen= RNA_property_array_length(ptr, prop); if(arraylen && index == -1) return NULL; if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, OPTION, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, OPTION, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_INT: case PROP_FLOAT: + { + int arraylen= RNA_property_array_length(ptr, prop); + if(arraylen && index == -1) { if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) - but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, COL, 0, name, x1, y1, x2, y2, ptr, prop, 0, 0, 0, -1, -1, NULL); } else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) - but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; + } case PROP_ENUM: if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_STRING: if(icon && name && name[0] == '\0') - but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconButR_prop(block, TEX, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else if(icon) - but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); else - but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefButR_prop(block, TEX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; case PROP_POINTER: { PointerRNA pptr; @@ -112,7 +109,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if(icon == ICON_DOT) icon= 0; - but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + but= uiDefIconTextButR_prop(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); break; } case PROP_COLLECTION: { @@ -146,7 +143,7 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr, int (*check_prop)(Proper if(label_align != '\0') { PropertyType type = RNA_property_type(prop); - int is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(ptr, prop)); + int is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop)); name= RNA_property_ui_name(prop); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 25a64994f5c..5da875356ea 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -180,7 +180,7 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y glEnable(GL_BLEND); glGetFloatv(GL_CURRENT_COLOR, color); - color[3]*= 0.125; + color[3] *= 0.125f; glColor4fv(color); /* for each AA step */ @@ -771,7 +771,6 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect) /* icons have been standardized... and this call draws in untransformed coordinates */ -#define ICON_HEIGHT UI_DPI_FAC*16.0f static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) { @@ -791,15 +790,15 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect if(aspect != but->aspect) { /* prevent scaling up icon in pupmenu */ if (aspect < 1.0f) { - height= ICON_HEIGHT; + height= UI_DPI_ICON_SIZE; aspect = 1.0f; } else - height= ICON_HEIGHT/aspect; + height= UI_DPI_ICON_SIZE/aspect; } else - height= ICON_HEIGHT; + height= UI_DPI_ICON_SIZE; /* calculate blend color */ if ELEM4(but->type, TOG, ROW, TOGN, LISTROW) { @@ -866,7 +865,7 @@ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10; int okwidth= rect->xmax-rect->xmin - border; - if (but->flag & UI_HAS_ICON) okwidth -= 16; + if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; /* need to set this first */ uiStyleFontSet(fstyle); @@ -1149,7 +1148,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB if (but->flag & UI_HAS_ICON) { widget_draw_icon(but, but->icon+but->iconadd, 1.0f, rect); - rect->xmin += UI_icon_get_width(but->icon+but->iconadd); + rect->xmin += (int)((float)UI_icon_get_width(but->icon+but->iconadd) * UI_DPI_ICON_FAC); if(but->editstr || (but->flag & UI_TEXT_LEFT)) rect->xmin += 5; @@ -3133,7 +3132,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic /* text location offset */ rect->xmin+=5; - if(iconid) rect->xmin+= ICON_HEIGHT; + if(iconid) rect->xmin+= UI_DPI_ICON_SIZE; /* cut string in 2 parts? */ cpoin= strchr(name, '|'); @@ -3158,7 +3157,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic if(iconid) { int xs= rect->xmin+4; - int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2; + int ys= 1 + (rect->ymin+rect->ymax- UI_DPI_ICON_SIZE)/2; glEnable(GL_BLEND); UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */ glDisable(GL_BLEND); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 32e87b3a793..e71f709f89b 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1425,7 +1425,7 @@ void init_userdef_do_versions(void) if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 8)) { wmKeyMap *km; - for(km=U.keymaps.first; km; km=km->next) { + for(km=U.user_keymaps.first; km; km=km->next) { if (strcmp(km->idname, "Armature_Sketch")==0) strcpy(km->idname, "Armature Sketch"); else if (strcmp(km->idname, "View3D")==0) @@ -1557,7 +1557,7 @@ void init_userdef_do_versions(void) U.autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET; } - if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 1)) { + if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 2)) { bTheme *btheme; for(btheme= U.themes.first; btheme; btheme= btheme->next) { btheme->tnode.noodle_curving = 5; diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index 34936c025bc..b992ae5f04c 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -8,7 +8,7 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../gpu ../../blenloader' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index ec08bfccda3..4377fb03632 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1449,9 +1449,8 @@ static int mesh_separate_material(wmOperator *op, Main *bmain, Scene *scene, Bas /* select the material */ EM_select_by_material(em, curr_mat); /* and now separate */ - if(0==mesh_separate_selected(op, bmain, scene, editbase)) { - BKE_mesh_end_editmesh(me, em); - return 0; + if(em->totfacesel > 0) { + mesh_separate_selected(op, bmain, scene, editbase); } } diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 9497370a4fa..eb6854d2548 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -1697,7 +1697,7 @@ void EM_mesh_copy_face_layer(EditMesh *em, wmOperator *op, short type) /* ctrl+c in mesh editmode */ -static void mesh_copy_menu(EditMesh *em, wmOperator *op) +static void UNUSED_FUNCTION(mesh_copy_menu)(EditMesh *em, wmOperator *op) { EditSelection *ese; int ret; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index bfae101d38e..9ff2923f733 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3895,7 +3895,7 @@ void MESH_OT_edge_rotate(wmOperatorType *ot) /* XXX old bevel not ported yet */ -static void bevel_menu(EditMesh *em) +static void UNUSED_FUNCTION(bevel_menu)(EditMesh *em) { BME_Mesh *bm; BME_TransData_Head *td; diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index 660643fbb0f..ca048cb59f9 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -10,7 +10,7 @@ incs += ' ../../render/extern/include ../../gpu' # for object_bake.c defs = [] -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index f5f97c6a5f6..d5f10f1d37d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -182,7 +182,7 @@ void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode) } RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object", -FLT_MAX, FLT_MAX); - RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", -FLT_MAX, FLT_MAX); + RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", (float)-M_PI * 2.0f, (float)M_PI * 2.0f); prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", ""); RNA_def_property_flag(prop, PROP_HIDDEN); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 679e4e58017..ee162464c70 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -636,14 +636,14 @@ static void apply_heights_data(void *bake_data) if(ibuf->rect_float) { float *rrgbf= ibuf->rect_float + i*4; - if(max-min > 1e-5) height= (heights[i]-min)/(max-min); + if(max-min > 1e-5f) height= (heights[i]-min)/(max-min); else height= 0; rrgbf[0]=rrgbf[1]=rrgbf[2]= height; } else { char *rrgb= (char*)ibuf->rect + i*4; - if(max-min > 1e-5) height= (heights[i]-min)/(max-min); + if(max-min > 1e-5f) height= (heights[i]-min)/(max-min); else height= 0; rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 395705dc029..61734bc51a2 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -721,7 +721,7 @@ static void spot_interactive(Object *ob, int mode) } #endif -static void special_editmenu(Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(special_editmenu)(Scene *scene, View3D *v3d) { // XXX static short numcuts= 2; Object *ob= OBACT; @@ -1049,109 +1049,6 @@ static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob) } } -static void copymenu_modifiers(Main *bmain, Scene *scene, View3D *v3d, Object *ob) -{ - Base *base; - int i, event; - char str[512]; - const char *errorstr= NULL; - - strcpy(str, "Copy Modifiers %t"); - - sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES); - - for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) { - ModifierTypeInfo *mti = modifierType_getInfo(i); - - if(ELEM3(i, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; - - if(i == eModifierType_Collision) - continue; - - if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) || - (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) { - sprintf(str+strlen(str), "|%s%%x%d", mti->name, i); - } - } - - event = pupmenu(str); - if(event<=0) return; - - for (base= FIRSTBASE; base; base= base->next) { - if(base->object != ob) { - if(TESTBASELIB(v3d, base)) { - - base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA; - - if (base->object->type==ob->type) { - /* copy all */ - if (event==NUM_MODIFIER_TYPES) { - ModifierData *md; - object_free_modifiers(base->object); - - for (md=ob->modifiers.first; md; md=md->next) { - ModifierData *nmd = NULL; - - if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue; - - if(md->type == eModifierType_Collision) - continue; - - nmd = modifier_new(md->type); - modifier_copyData(md, nmd); - BLI_addtail(&base->object->modifiers, nmd); - modifier_unique_name(&base->object->modifiers, nmd); - } - - copy_object_particlesystems(base->object, ob); - copy_object_softbody(base->object, ob); - } else { - /* copy specific types */ - ModifierData *md, *mdn; - - /* remove all with type 'event' */ - for (md=base->object->modifiers.first; md; md=mdn) { - mdn= md->next; - if(md->type==event) { - BLI_remlink(&base->object->modifiers, md); - modifier_free(md); - } - } - - /* copy all with type 'event' */ - for (md=ob->modifiers.first; md; md=md->next) { - if (md->type==event) { - - mdn = modifier_new(event); - BLI_addtail(&base->object->modifiers, mdn); - modifier_unique_name(&base->object->modifiers, mdn); - - modifier_copyData(md, mdn); - } - } - - if(event == eModifierType_ParticleSystem) { - object_free_particlesystems(base->object); - copy_object_particlesystems(base->object, ob); - } - else if(event == eModifierType_Softbody) { - object_free_softbody(base->object); - copy_object_softbody(base->object, ob); - } - } - } - else - errorstr= "Did not copy modifiers to other Object types"; - } - } - } - -// if(errorstr) notice(errorstr); - - DAG_scene_sort(bmain, scene); - -} - /* both pointers should exist */ static void copy_texture_space(Object *to, Object *ob) { @@ -1196,6 +1093,7 @@ static void copy_texture_space(Object *to, Object *ob) } +/* UNUSED, keep incase we want to copy functionality for use elsewhere */ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) { Object *ob; @@ -1221,7 +1119,8 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) return; } else if(event==24) { - copymenu_modifiers(bmain, scene, v3d, ob); + /* moved to object_link_modifiers */ + /* copymenu_modifiers(bmain, scene, v3d, ob); */ return; } @@ -1444,7 +1343,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) DAG_ids_flush_update(bmain, 0); } -static void copy_attr_menu(Main *bmain, Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(copy_attr_menu)(Main *bmain, Scene *scene, View3D *v3d) { Object *ob; short event; @@ -1717,7 +1616,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) /* ********************** */ -static void image_aspect(Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(image_aspect)(Scene *scene, View3D *v3d) { /* all selected objects with an image map: scale in image aspect */ Base *base; @@ -1792,7 +1691,7 @@ static int vergbaseco(const void *a1, const void *a2) } -static void auto_timeoffs(Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(auto_timeoffs)(Scene *scene, View3D *v3d) { Base *base, **basesort, **bs; float start, delta; @@ -1833,7 +1732,7 @@ static void auto_timeoffs(Scene *scene, View3D *v3d) } -static void ofs_timeoffs(Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(ofs_timeoffs)(Scene *scene, View3D *v3d) { float offset=0.0f; @@ -1852,7 +1751,7 @@ static void ofs_timeoffs(Scene *scene, View3D *v3d) } -static void rand_timeoffs(Scene *scene, View3D *v3d) +static void UNUSED_FUNCTION(rand_timeoffs)(Scene *scene, View3D *v3d) { Base *base; float rand_ofs=0.0f; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 0fb7cf8b640..225e6e73563 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1402,6 +1402,20 @@ static void single_object_users(Scene *scene, View3D *v3d, int flag) set_sca_new_poins(); } +/* not an especially efficient function, only added so the single user + * button can be functional.*/ +void ED_object_single_user(Scene *scene, Object *ob) +{ + Base *base; + + for(base= FIRSTBASE; base; base= base->next) { + if(base->object == ob) base->flag |= OB_DONE; + else base->flag &= ~OB_DONE; + } + + single_object_users(scene, NULL, OB_DONE); +} + static void new_id_matar(Material **matar, int totcol) { ID *id; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index f7c6ff99bde..78f3537bea9 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -246,7 +246,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, } /* tag for updates */ - ob->recalc |= OB_RECALC_OB; + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } CTX_DATA_END; @@ -341,7 +341,8 @@ static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op)) negate_v3_v3(v3, v1); mul_m3_v3(mat, v3); } - ob->recalc |= OB_RECALC_OB; + + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; @@ -871,7 +872,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) (ob->dup_group==ob_other->dup_group && (ob->transflag|ob_other->transflag) & OB_DUPLIGROUP) ) ) { ob_other->flag |= OB_DONE; - ob_other->recalc= OB_RECALC_OB|OB_RECALC_DATA; + DAG_id_tag_update(&ob_other->id, OB_RECALC_OB|OB_RECALC_DATA); copy_v3_v3(centn, cent); mul_mat3_m4_v3(ob_other->obmat, centn); /* ommit translation part */ @@ -890,11 +891,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - for (tob= bmain->object.first; tob; tob= tob->id.next) { - if(tob->data && (((ID *)tob->data)->flag & LIB_DOIT)) { - tob->recalc= OB_RECALC_OB|OB_RECALC_DATA; - } - } + for (tob= bmain->object.first; tob; tob= tob->id.next) + if(tob->data && (((ID *)tob->data)->flag & LIB_DOIT)) + DAG_id_tag_update(&tob->id, OB_RECALC_OB|OB_RECALC_DATA); if (tot_change) { DAG_ids_flush_update(bmain, 0); diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript index 274819c918c..188416eb04c 100644 --- a/source/blender/editors/physics/SConscript +++ b/source/blender/editors/physics/SConscript @@ -10,7 +10,7 @@ incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' defs = '' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index 2b9737557cd..53418500ea6 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -9,7 +9,7 @@ incs += ' ../../gpu' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' incs += ' ../../blenloader' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index cfed2750e18..fbdcf7ba9b3 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -787,7 +787,7 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot) ot->poll= envmap_save_poll; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */ /* properties */ //RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as."); @@ -875,8 +875,6 @@ static int copy_material_exec(bContext *C, wmOperator *UNUSED(op)) copy_matcopybuf(ma); - WM_event_add_notifier(C, NC_MATERIAL, ma); - return OPERATOR_FINISHED; } @@ -891,7 +889,7 @@ void MATERIAL_OT_copy(wmOperatorType *ot) ot->exec= copy_material_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* no undo needed since no changes are made to the material */ } static int paste_material_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1015,8 +1013,6 @@ static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op)) copy_mtex_copybuf(id); - WM_event_add_notifier(C, NC_TEXTURE, NULL); - return OPERATOR_FINISHED; } @@ -1039,7 +1035,7 @@ void TEXTURE_OT_slot_copy(wmOperatorType *ot) ot->poll= copy_mtex_poll; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* no undo needed since no changes are made to the mtex */ } static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 98f42fe97c1..85e1eb016d7 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -24,7 +24,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/render/render_shading.c +/** \file blender/editors/render/render_update.c * \ingroup edrend */ @@ -58,6 +58,7 @@ #include "GPU_material.h" +#include "ED_node.h" #include "ED_render.h" #include "render_intern.h" // own include @@ -115,6 +116,8 @@ static void texture_changed(Main *bmain, Tex *tex) Material *ma; Lamp *la; World *wo; + Scene *scene; + bNode *node; /* icons */ BKE_icon_changed(BKE_icon_getid(&tex->id)); @@ -146,6 +149,16 @@ static void texture_changed(Main *bmain, Tex *tex) BKE_icon_changed(BKE_icon_getid(&wo->id)); } + + /* find compositing nodes */ + for(scene=bmain->scene.first; scene; scene=scene->id.next) { + if(scene->use_nodes && scene->nodetree) { + for(node=scene->nodetree->nodes.first; node; node=node->next) { + if(node->id == &tex->id) + ED_node_changed_update(&scene->id, node); + } + } + } } static void lamp_changed(Main *bmain, Lamp *la) diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index 61f3429521d..1381c820224 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -10,7 +10,7 @@ incs += ' #/intern/guardedalloc #/extern/glew/include' defs = '' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 82986dfbcc4..bc97cd9d3ff 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1406,6 +1406,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) "Displays current editor type. " "Click for menu of available types"); uiButSetFunc(but, spacefunc, NULL, NULL); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ return xco + UI_UNIT_X + 14; } @@ -1414,6 +1415,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) { ScrArea *sa= CTX_wm_area(C); int xco= 8; + uiBut *but; if (!sa->full) xco= ED_area_header_switchbutton(C, block, yco); @@ -1421,20 +1423,22 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) uiBlockSetEmboss(block, UI_EMBOSSN); if (sa->flag & HEADER_NO_PULLDOWN) { - uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, + but= uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_RIGHT, xco,yco,UI_UNIT_X,UI_UNIT_Y-2, &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); } else { - uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, + but= uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_DOWN, xco,yco,UI_UNIT_X,UI_UNIT_Y-2, &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); } + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + uiBlockSetEmboss(block, UI_EMBOSS); return xco + UI_UNIT_X; diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript index 90b56ded2cd..b3927fcee68 100644 --- a/source/blender/editors/sculpt_paint/SConscript +++ b/source/blender/editors/sculpt_paint/SConscript @@ -10,7 +10,7 @@ incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../render/extern/include' incs += ' ../../gpu ../../makesrna ../../blenloader' -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 56226280554..3f23b81ca3b 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -914,6 +914,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) block= uiLayoutGetBlock(row); uiBlockSetEmboss(block, UI_EMBOSSN); but= uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag, 0, 0, 0, 0, "Follow context or keep fixed datablock displayed"); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ uiButSetFunc(but, pin_cb, NULL, NULL); for(a=0; a<path->len; a++) { diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index 19c600be937..e631718b0cb 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -104,6 +104,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) { SpaceButs *sbuts= CTX_wm_space_buts(C); uiBlock *block; + uiBut *but; int xco, yco= 2; buttons_context_compute(C, sbuts); @@ -118,33 +119,32 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) xco -= UI_UNIT_X; // Default panels + uiBlockBeginAlign(block); - if(sbuts->pathflag & (1<<BCONTEXT_RENDER)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_SCENE, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_RENDER, 0, 0, "Render"); - if(sbuts->pathflag & (1<<BCONTEXT_SCENE)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_SCENE_DATA, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_SCENE, 0, 0, "Scene"); - if(sbuts->pathflag & (1<<BCONTEXT_WORLD)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_WORLD, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_WORLD, 0, 0, "World"); - if(sbuts->pathflag & (1<<BCONTEXT_OBJECT)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_OBJECT_DATA, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object"); - if(sbuts->pathflag & (1<<BCONTEXT_CONSTRAINT)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Object Constraints"); - if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifiers"); - if(sbuts->pathflag & (1<<BCONTEXT_DATA)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, sbuts->dataicon, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data"); - if(sbuts->pathflag & (1<<BCONTEXT_BONE)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_BONE_DATA, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone"); - if(sbuts->pathflag & (1<<BCONTEXT_BONE_CONSTRAINT)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT_BONE, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE_CONSTRAINT, 0, 0, "Bone Constraints"); - if(sbuts->pathflag & (1<<BCONTEXT_MATERIAL)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MATERIAL, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_MATERIAL, 0, 0, "Material"); - if(sbuts->pathflag & (1<<BCONTEXT_TEXTURE)) - uiDefIconButS(block, ROW, B_BUTSPREVIEW, ICON_TEXTURE, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_TEXTURE, 0, 0, "Texture"); - if(sbuts->pathflag & (1<<BCONTEXT_PARTICLE)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_PARTICLES, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_PARTICLE, 0, 0, "Particles"); - if(sbuts->pathflag & (1<<BCONTEXT_PHYSICS)) - uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_PHYSICS, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)BCONTEXT_PHYSICS, 0, 0, "Physics"); + +#define BUTTON_HEADER_CTX(_ctx, _icon, _tip) \ + if(sbuts->pathflag & (1<<_ctx)) { \ + but= uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, _icon, xco+=BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, &(sbuts->mainb), 0.0, (float)_ctx, 0, 0, _tip); \ + uiButClearFlag(but, UI_BUT_UNDO); \ + } \ + + + BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, "Render") + BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, "Scene"); + BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, "World"); + BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, "Object"); + BUTTON_HEADER_CTX(BCONTEXT_CONSTRAINT, ICON_CONSTRAINT, "Object Constraints"); + BUTTON_HEADER_CTX(BCONTEXT_MODIFIER, ICON_MODIFIER, "Object Modifiers"); + BUTTON_HEADER_CTX(BCONTEXT_DATA, sbuts->dataicon, "Object Data"); + BUTTON_HEADER_CTX(BCONTEXT_BONE, ICON_BONE_DATA, "Bone"); + BUTTON_HEADER_CTX(BCONTEXT_BONE_CONSTRAINT, ICON_CONSTRAINT_BONE, "Bone Constraints"); + BUTTON_HEADER_CTX(BCONTEXT_MATERIAL, ICON_MATERIAL, "Material"); + BUTTON_HEADER_CTX(BCONTEXT_TEXTURE, ICON_TEXTURE, "Textures"); + BUTTON_HEADER_CTX(BCONTEXT_PARTICLE, ICON_PARTICLES, "Particles"); + BUTTON_HEADER_CTX(BCONTEXT_PHYSICS, ICON_PHYSICS, "Physics"); + +#undef BUTTON_HEADER_CTX + xco+= BUT_UNIT_X; uiBlockEndAlign(block); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 3effea296d7..4707baa279b 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -675,7 +675,12 @@ static int scrollback_append_exec(bContext *C, wmOperator *op) console_scrollback_limit(sc); - console_textview_update_rect(sc, ar); + /* 'ar' can be null depending on the operator that runs + * rendering with invoke default for eg causes this */ + if(ar) { + console_textview_update_rect(sc, ar); + } + ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript index 7c55b40e816..ad96840f7b9 100644 --- a/source/blender/editors/space_file/SConscript +++ b/source/blender/editors/space_file/SConscript @@ -19,7 +19,7 @@ if env['WITH_BF_OPENEXR']: if env['WITH_BF_TIFF']: defs.append('WITH_TIFF') -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index d4253495e97..4dd97c63d40 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1159,6 +1159,13 @@ int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) return OPERATOR_FINISHED; } +/* TODO, directory operator is non-functional while a library is loaded + * until this is properly supported just disable it. */ +static int file_directory_poll(bContext *C) +{ + return ED_operator_file_active(C) && filelist_lib(CTX_wm_space_file(C)->files) == NULL; +} + void FILE_OT_directory(struct wmOperatorType *ot) { /* identifiers */ @@ -1169,7 +1176,7 @@ void FILE_OT_directory(struct wmOperatorType *ot) /* api callbacks */ ot->invoke= file_directory_invoke; ot->exec= file_directory_exec; - ot->poll= ED_operator_file_active; /* <- important, handler is on window level */ + ot->poll= file_directory_poll; /* <- important, handler is on window level */ } void FILE_OT_refresh(struct wmOperatorType *ot) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 6736230e84f..d8be312cf39 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -602,28 +602,6 @@ short filelist_changed(struct FileList* filelist) return filelist->changed; } -static struct ImBuf * filelist_loadimage(struct FileList* filelist, int index) -{ - ImBuf *imb = NULL; - int fidx = 0; - - if ( (index < 0) || (index >= filelist->numfiltered) ) { - return NULL; - } - fidx = filelist->fidx[index]; - imb = filelist->filelist[fidx].image; - if (!imb) - { - if ( (filelist->filelist[fidx].flags & IMAGEFILE) || (filelist->filelist[fidx].flags & MOVIEFILE) ) { - imb = IMB_thumb_read(filelist->filelist[fidx].path, THB_NORMAL); - } - if (imb) { - filelist->filelist[fidx].image = imb; - } - } - return imb; -} - struct ImBuf * filelist_getimage(struct FileList* filelist, int index) { ImBuf* ibuf = NULL; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index e0ebde589a8..6e0d1909963 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -447,34 +447,41 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot) static int view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { - SpaceImage *sima= CTX_wm_space_image(C); - ARegion *ar= CTX_wm_region(C); + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + SpaceImage *sima= CTX_wm_space_image(C); + ARegion *ar= CTX_wm_region(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - float dt = ndof->dt; - /* tune these until it feels right */ - const float zoom_sensitivity = 0.5f; // 50% per second (I think) - const float pan_sensitivity = 300.f; // screen pixels per second + float dt = ndof->dt; + /* tune these until it feels right */ + const float zoom_sensitivity = 0.5f; // 50% per second (I think) + const float pan_sensitivity = 300.f; // screen pixels per second - float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom; - float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom; + float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom; + float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom; - /* "mouse zoom" factor = 1 + (dx + dy) / 300 - * what about "ndof zoom" factor? should behave like this: - * at rest -> factor = 1 - * move forward -> factor > 1 - * move backward -> factor < 1 - */ - float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2]; + /* "mouse zoom" factor = 1 + (dx + dy) / 300 + * what about "ndof zoom" factor? should behave like this: + * at rest -> factor = 1 + * move forward -> factor > 1 + * move backward -> factor < 1 + */ + float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2]; - sima_zoom_set_factor(sima, ar, zoom_factor); - sima->xof += pan_x; - sima->yof += pan_y; + if (U.ndof_flag & NDOF_ZOOM_INVERT) + zoom_factor = -zoom_factor; - ED_region_tag_redraw(ar); + sima_zoom_set_factor(sima, ar, zoom_factor); + sima->xof += pan_x; + sima->yof += pan_y; - return OPERATOR_FINISHED; + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; + } } void IMAGE_OT_view_ndof(wmOperatorType *ot) @@ -1324,7 +1331,7 @@ void IMAGE_OT_reload(wmOperatorType *ot) ot->exec= reload_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* no undo, image buffer is not handled by undo */ } /********************** new image operator *********************/ @@ -1982,7 +1989,7 @@ void IMAGE_OT_sample_line(wmOperatorType *ot) ot->cancel= WM_gesture_straightline_cancel; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= 0; /* no undo/register since this operates on the space */ WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT); } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index d58fb7b11f0..e09565d38e9 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -273,7 +273,7 @@ void FILE_OT_report_missing_files(wmOperatorType *ot) ot->exec= report_missing_files_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= 0; /* only reports so no need to undo/register */ } /********************* find missing files operator *********************/ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 77c91b28a63..af99087b0b8 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -951,7 +951,7 @@ static int nlaedit_bake_exec (bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static void NLA_OT_bake (wmOperatorType *ot) +void NLA_OT_bake (wmOperatorType *ot) { /* identifiers */ ot->name= "Bake Strips"; diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript index 634d4b777d9..c4309dcfca3 100644 --- a/source/blender/editors/space_node/SConscript +++ b/source/blender/editors/space_node/SConscript @@ -15,7 +15,7 @@ if env['CC'] == 'gcc': #cf.append('-Werror') pass -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c719f749582..011f9a31c93 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -479,72 +479,90 @@ static void snode_tag_changed(SpaceNode *snode, bNode *node) NodeTagIDChanged(snode->nodetree, gnode->id); } -void node_set_active(SpaceNode *snode, bNode *node) +static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup) { - nodeSetActive(snode->edittree, node); + bNode *node; + + if(ntree == lookup) + return 1; + + for(node=ntree->nodes.first; node; node=node->next) + if(node->type == NODE_GROUP && node->id) + if(has_nodetree((bNodeTree*)node->id, lookup)) + return 1; + + return 0; +} + +void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) +{ + nodeSetActive(ntree, node); if(node->type!=NODE_GROUP) { int was_output= (node->flag & NODE_DO_OUTPUT); /* tree specific activate calls */ - if(snode->treetype==NTREE_SHADER) { + if(ntree->type==NTREE_SHADER) { /* when we select a material, active texture is cleared, for buttons */ if(node->id && GS(node->id->name)==ID_MA) - nodeClearActiveID(snode->edittree, ID_TE); + nodeClearActiveID(ntree, ID_TE); if(node->type==SH_NODE_OUTPUT) { bNode *tnode; - for(tnode= snode->edittree->nodes.first; tnode; tnode= tnode->next) + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) if( tnode->type==SH_NODE_OUTPUT) tnode->flag &= ~NODE_DO_OUTPUT; node->flag |= NODE_DO_OUTPUT; if(was_output==0) - ED_node_changed_update(snode->id, node); + ED_node_generic_update(bmain, ntree, node); } WM_main_add_notifier(NC_MATERIAL|ND_NODES, node->id); } - else if(snode->treetype==NTREE_COMPOSIT) { - Scene *scene= (Scene*)snode->id; - + else if(ntree->type==NTREE_COMPOSIT) { /* make active viewer, currently only 1 supported... */ if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { bNode *tnode; - for(tnode= snode->edittree->nodes.first; tnode; tnode= tnode->next) + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) if( ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) tnode->flag &= ~NODE_DO_OUTPUT; node->flag |= NODE_DO_OUTPUT; - if(was_output==0) { - snode_tag_changed(snode, node); - - ED_node_changed_update(snode->id, node); - } + if(was_output==0) + ED_node_generic_update(bmain, ntree, node); /* addnode() doesnt link this yet... */ node->id= (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } else if(node->type==CMP_NODE_R_LAYERS) { - if(node->id==NULL || node->id==(ID *)scene) { - scene->r.actlay= node->custom1; + Scene *scene; + + for(scene=bmain->scene.first; scene; scene=scene->id.next) { + if(scene->nodetree && scene->use_nodes && has_nodetree(scene->nodetree, ntree)) { + if(node->id==NULL || node->id==(ID *)scene) { + scene->r.actlay= node->custom1; + } + } } } else if(node->type==CMP_NODE_COMPOSITE) { - bNode *tnode; - - for(tnode= snode->edittree->nodes.first; tnode; tnode= tnode->next) - if( tnode->type==CMP_NODE_COMPOSITE) - tnode->flag &= ~NODE_DO_OUTPUT; - - node->flag |= NODE_DO_OUTPUT; - ED_node_changed_update(snode->id, node); + if (was_output==0) { + bNode *tnode; + + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) + if( tnode->type==CMP_NODE_COMPOSITE) + tnode->flag &= ~NODE_DO_OUTPUT; + + node->flag |= NODE_DO_OUTPUT; + ED_node_generic_update(bmain, ntree, node); + } } } - else if(snode->treetype==NTREE_TEXTURE) { + else if(ntree->type==NTREE_TEXTURE) { // XXX #if 0 if(node->id) @@ -1625,7 +1643,7 @@ void NODE_OT_link_viewer(wmOperatorType *ot) /* return 0, nothing done */ -static int node_mouse_groupheader(SpaceNode *snode) +static int UNUSED_FUNCTION(node_mouse_groupheader)(SpaceNode *snode) { bNode *gnode; float mx=0, my=0; @@ -1940,7 +1958,7 @@ void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace) } /* can be called from menus too, but they should do own undopush and redraws */ -bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float locy) +bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, int type, float locx, float locy) { bNode *node= NULL, *gnode; @@ -1955,7 +1973,7 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float return NULL; } else { - bNodeTree *ngroup= BLI_findlink(&G.main->nodetree, type-NODE_GROUP_MENU); + bNodeTree *ngroup= BLI_findlink(&bmain->nodetree, type-NODE_GROUP_MENU); if(ngroup) node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup, NULL); } @@ -1976,7 +1994,7 @@ bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float } node_tree_verify_groups(snode->nodetree); - node_set_active(snode, node); + ED_node_set_active(bmain, snode->edittree, node); if(snode->nodetree->type==NTREE_COMPOSIT) { if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) @@ -2991,10 +3009,10 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - if(node->inputs.first && node->outputs.first) { + /* Be able to mute in-/output nodes as well. - DingTo + if(node->inputs.first && node->outputs.first) { */ node->flag ^= NODE_MUTED; snode_tag_changed(snode, node); - } } } @@ -3205,6 +3223,7 @@ void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot) static int node_add_file_exec(bContext *C, wmOperator *op) { + Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); bNode *node; @@ -3245,7 +3264,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(C); - node = node_add_node(snode, scene, ntype, snode->mx, snode->my); + node = node_add_node(snode, bmain, scene, ntype, snode->mx, snode->my); if (!node) { BKE_report(op->reports, RPT_WARNING, "Could not add an image node."); diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 4f3991e8ff8..634e49dc515 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -64,6 +64,8 @@ static void do_node_add(bContext *C, void *UNUSED(arg), int event) { + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); ScrArea *sa= CTX_wm_area(C); ARegion *ar; @@ -87,7 +89,7 @@ static void do_node_add(bContext *C, void *UNUSED(arg), int event) else node->flag &= ~NODE_TEST; } - node= node_add_node(snode, CTX_data_scene(C), event, snode->mx, snode->my); + node= node_add_node(snode, bmain, scene, event, snode->mx, snode->my); /* select previous selection before autoconnect */ for(node= snode->edittree->nodes.first; node; node= node->next) { diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9122235f33c..4cfde22b8a0 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -43,6 +43,7 @@ struct wmWindowManager; struct bNode; struct bNodeSocket; struct bNodeLink; +struct Main; /* temp data to pass on to modal */ typedef struct bNodeLinkDrag @@ -97,10 +98,9 @@ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *tre void snode_notify(bContext *C, SpaceNode *snode); void snode_dag_update(bContext *C, SpaceNode *snode); bNode *next_node(bNodeTree *ntree); -bNode *node_add_node(SpaceNode *snode, Scene *scene, int type, float locx, float locy); +bNode *node_add_node(SpaceNode *snode, struct Main *bmain, Scene *scene, int type, float locx, float locy); void snode_set_context(SpaceNode *snode, Scene *scene); void snode_make_group_editable(SpaceNode *snode, bNode *gnode); -void node_set_active(SpaceNode *snode, bNode *node); void node_deselectall(SpaceNode *snode); int node_select_same_type(SpaceNode *snode); int node_select_same_type_np(SpaceNode *snode, int dir); diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 1abcaccc939..ca673277739 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -37,10 +37,12 @@ #include "DNA_scene_types.h" #include "BKE_context.h" +#include "BKE_main.h" #include "BLI_rect.h" #include "BLI_utildefines.h" +#include "ED_node.h" #include "ED_screen.h" #include "ED_types.h" @@ -70,7 +72,7 @@ static bNode *node_under_mouse(bNodeTree *ntree, int mx, int my) /* ****** Click Select ****** */ -static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, const int mval[2], short extend) +static bNode *node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend) { bNode *node; float mx, my; @@ -92,7 +94,7 @@ static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, const int mval[2] else node->flag ^= SELECT; - node_set_active(snode, node); + ED_node_set_active(bmain, snode->edittree, node); } return node; @@ -100,6 +102,7 @@ static bNode *node_mouse_select(SpaceNode *snode, ARegion *ar, const int mval[2] static int node_select_exec(bContext *C, wmOperator *op) { + Main *bmain= CTX_data_main(C); SpaceNode *snode= CTX_wm_space_node(C); ARegion *ar= CTX_wm_region(C); int mval[2]; @@ -113,7 +116,7 @@ static int node_select_exec(bContext *C, wmOperator *op) extend = RNA_boolean_get(op->ptr, "extend"); /* perform the select */ - node= node_mouse_select(snode, ar, mval, extend); + node= node_mouse_select(bmain, snode, ar, mval, extend); /* send notifiers */ WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 4194d463e10..d969a80a678 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -37,8 +37,12 @@ set(INC_SYS ) set(SRC - outliner.c + outliner_draw.c + outliner_edit.c outliner_ops.c + outliner_select.c + outliner_tools.c + outliner_tree.c space_outliner.c outliner_intern.h diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c deleted file mode 100644 index ceb80e06d34..00000000000 --- a/source/blender/editors/space_outliner/outliner.c +++ /dev/null @@ -1,5794 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2004 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_outliner/outliner.c - * \ingroup spoutliner - */ - - -#include <math.h> -#include <string.h> -#include <stdlib.h> -#include <stddef.h> - -#include "MEM_guardedalloc.h" - -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_camera_types.h" -#include "DNA_group_types.h" -#include "DNA_key_types.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meta_types.h" -#include "DNA_particle_types.h" -#include "DNA_scene_types.h" -#include "DNA_world_types.h" -#include "DNA_sequence_types.h" -#include "DNA_object_types.h" - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" -#include "BLI_math_base.h" - -#if defined WIN32 && !defined _LIBC -# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ -#else -# ifndef _GNU_SOURCE -# define _GNU_SOURCE -# endif -# include <fnmatch.h> -#endif - - -#include "BKE_animsys.h" -#include "BKE_context.h" -#include "BKE_deform.h" -#include "BKE_depsgraph.h" -#include "BKE_fcurve.h" -#include "BKE_global.h" -#include "BKE_group.h" -#include "BKE_library.h" -#include "BKE_main.h" -#include "BKE_modifier.h" -#include "BKE_report.h" -#include "BKE_scene.h" -#include "BKE_sequencer.h" - -#include "ED_armature.h" -#include "ED_object.h" -#include "ED_screen.h" -#include "ED_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "UI_interface.h" -#include "UI_interface_icons.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "ED_keyframing.h" - -#include "outliner_intern.h" - - -#define OL_Y_OFFSET 2 - -#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X*3) -#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X*2) -#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X - -#define OL_TOGW OL_TOG_RESTRICT_VIEWX - -#define OL_RNA_COLX (UI_UNIT_X*15) -#define OL_RNA_COL_SIZEX (UI_UNIT_X*7.5) -#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5) - -#define TS_CHUNK 128 - -#define TREESTORE(a) ((a)?soops->treestore->data+(a)->store_index:NULL) - -/* ************* XXX **************** */ - -static void error(const char *UNUSED(arg), ...) {} - -/* ********************************** */ - - -/* ******************** PROTOTYPES ***************** */ -static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty); -static void outliner_do_object_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, - void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)); - -static int group_select_flag(Group *gr); - -/* ******************** PERSISTANT DATA ***************** */ - -static void outliner_storage_cleanup(SpaceOops *soops) -{ - TreeStore *ts= soops->treestore; - - if(ts) { - TreeStoreElem *tselem; - int a, unused= 0; - - /* each element used once, for ID blocks with more users to have each a treestore */ - for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) tselem->used= 0; - - /* cleanup only after reading file or undo step, and always for - * RNA datablocks view in order to save memory */ - if(soops->storeflag & SO_TREESTORE_CLEANUP) { - - for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) { - if(tselem->id==NULL) unused++; - } - - if(unused) { - if(ts->usedelem == unused) { - MEM_freeN(ts->data); - ts->data= NULL; - ts->usedelem= ts->totelem= 0; - } - else { - TreeStoreElem *tsnewar, *tsnew; - - tsnew=tsnewar= MEM_mallocN((ts->usedelem-unused)*sizeof(TreeStoreElem), "new tselem"); - for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) { - if(tselem->id) { - *tsnew= *tselem; - tsnew++; - } - } - MEM_freeN(ts->data); - ts->data= tsnewar; - ts->usedelem-= unused; - ts->totelem= ts->usedelem; - } - } - } - } -} - -static void check_persistant(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) -{ - TreeStore *ts; - TreeStoreElem *tselem; - int a; - - /* case 1; no TreeStore */ - if(soops->treestore==NULL) { - soops->treestore= MEM_callocN(sizeof(TreeStore), "treestore"); - } - ts= soops->treestore; - - /* check if 'te' is in treestore */ - tselem= ts->data; - for(a=0; a<ts->usedelem; a++, tselem++) { - if(tselem->id==id && tselem->used==0) { - if((type==0 && tselem->type==0) ||(tselem->type==type && tselem->nr==nr)) { - te->store_index= a; - tselem->used= 1; - return; - } - } - } - - /* add 1 element to treestore */ - if(ts->usedelem==ts->totelem) { - TreeStoreElem *tsnew; - - tsnew= MEM_mallocN((ts->totelem+TS_CHUNK)*sizeof(TreeStoreElem), "treestore data"); - if(ts->data) { - memcpy(tsnew, ts->data, ts->totelem*sizeof(TreeStoreElem)); - MEM_freeN(ts->data); - } - ts->data= tsnew; - ts->totelem+= TS_CHUNK; - } - - tselem= ts->data+ts->usedelem; - - tselem->type= type; - if(type) tselem->nr= nr; // we're picky! :) - else tselem->nr= 0; - tselem->id= id; - tselem->used = 0; - tselem->flag= TSE_CLOSED; - te->store_index= ts->usedelem; - - ts->usedelem++; -} - -/* ******************** TREE MANAGEMENT ****************** */ - -void outliner_free_tree(ListBase *lb) -{ - - while(lb->first) { - TreeElement *te= lb->first; - - outliner_free_tree(&te->subtree); - BLI_remlink(lb, te); - - if(te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name); - MEM_freeN(te); - } -} - -static void outliner_height(SpaceOops *soops, ListBase *lb, int *h) -{ - TreeElement *te= lb->first; - while(te) { - TreeStoreElem *tselem= TREESTORE(te); - if((tselem->flag & TSE_CLOSED)==0) - outliner_height(soops, &te->subtree, h); - (*h) += UI_UNIT_Y; - te= te->next; - } -} - -#if 0 // XXX this is currently disabled until te->xend is set correctly -static void outliner_width(SpaceOops *soops, ListBase *lb, int *w) -{ - TreeElement *te= lb->first; - while(te) { -// TreeStoreElem *tselem= TREESTORE(te); - - // XXX fixme... te->xend is not set yet - if(tselem->flag & TSE_CLOSED) { - if (te->xend > *w) - *w = te->xend; - } - outliner_width(soops, &te->subtree, w); - te= te->next; - } -} -#endif - -static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int startx) -{ - TreeElement *te= lb->first; - while(te) { - TreeStoreElem *tselem= TREESTORE(te); - // XXX fixme... (currently, we're using a fixed length of 100)! - /*if(te->xend) { - if(te->xend > *w) - *w = te->xend; - }*/ - if(startx+100 > *w) - *w = startx+100; - - if((tselem->flag & TSE_CLOSED)==0) - outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X); - te= te->next; - } -} - -static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) -{ - TreeElement *te= lb->first, *tes; - while(te) { - if(te->store_index==store_index) return te; - tes= outliner_find_tree_element(&te->subtree, store_index); - if(tes) return tes; - te= te->next; - } - return NULL; -} - - - -static ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode) -{ - TreeStoreElem *tselem; - te= te->parent; - - while(te) { - tselem= TREESTORE(te); - if(tselem->type==0 && te->idcode==idcode) return tselem->id; - te= te->parent; - } - return NULL; -} - -struct treesort { - TreeElement *te; - ID *id; - const char *name; - short idcode; -}; - -static int treesort_alpha(const void *v1, const void *v2) -{ - const struct treesort *x1= v1, *x2= v2; - int comp; - - /* first put objects last (hierarchy) */ - comp= (x1->idcode==ID_OB); - if(x2->idcode==ID_OB) comp+=2; - - if(comp==1) return 1; - else if(comp==2) return -1; - else if(comp==3) { - comp= strcmp(x1->name, x2->name); - - if( comp>0 ) return 1; - else if( comp<0) return -1; - return 0; - } - return 0; -} - -/* this is nice option for later? doesnt look too useful... */ -#if 0 -static int treesort_obtype_alpha(const void *v1, const void *v2) -{ - const struct treesort *x1= v1, *x2= v2; - - /* first put objects last (hierarchy) */ - if(x1->idcode==ID_OB && x2->idcode!=ID_OB) return 1; - else if(x2->idcode==ID_OB && x1->idcode!=ID_OB) return -1; - else { - /* 2nd we check ob type */ - if(x1->idcode==ID_OB && x2->idcode==ID_OB) { - if( ((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1; - else if( ((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1; - else return 0; - } - else { - int comp= strcmp(x1->name, x2->name); - - if( comp>0 ) return 1; - else if( comp<0) return -1; - return 0; - } - } -} -#endif - -/* sort happens on each subtree individual */ -static void outliner_sort(SpaceOops *soops, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - int totelem=0; - - te= lb->last; - if(te==NULL) return; - tselem= TREESTORE(te); - - /* sorting rules; only object lists or deformgroups */ - if( (tselem->type==TSE_DEFGROUP) || (tselem->type==0 && te->idcode==ID_OB)) { - - /* count first */ - for(te= lb->first; te; te= te->next) totelem++; - - if(totelem>1) { - struct treesort *tear= MEM_mallocN(totelem*sizeof(struct treesort), "tree sort array"); - struct treesort *tp=tear; - int skip= 0; - - for(te= lb->first; te; te= te->next, tp++) { - tselem= TREESTORE(te); - tp->te= te; - tp->name= te->name; - tp->idcode= te->idcode; - if(tselem->type && tselem->type!=TSE_DEFGROUP) tp->idcode= 0; // dont sort this - tp->id= tselem->id; - } - /* keep beginning of list */ - for(tp= tear, skip=0; skip<totelem; skip++, tp++) - if(tp->idcode) break; - - if(skip<totelem) - qsort(tear+skip, totelem-skip, sizeof(struct treesort), treesort_alpha); - - lb->first=lb->last= NULL; - tp= tear; - while(totelem--) { - BLI_addtail(lb, tp->te); - tp++; - } - MEM_freeN(tear); - } - } - - for(te= lb->first; te; te= te->next) { - outliner_sort(soops, &te->subtree); - } -} - -/* Prototype, see functions below */ -static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index); - -#define LOG2I(x) (int)(log(x)/M_LN2) - -static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, SceneRenderLayer *srl) -{ - TreeStoreElem *tselem = NULL; - TreeElement *te = NULL; - - /* log stuff is to convert bitflags (powers of 2) to small integers, - * in order to not overflow short tselem->nr */ - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED)); - te->name= "Combined"; - te->directdata= &srl->passflag; - - /* save cpu cycles, but we add the first to invoke an open/close triangle */ - tselem = TREESTORE(tenla); - if(tselem->flag & TSE_CLOSED) - return; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z)); - te->name= "Z"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR)); - te->name= "Vector"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL)); - te->name= "Normal"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV)); - te->name= "UV"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST)); - te->name= "Mist"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB)); - te->name= "Index Object"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA)); - te->name= "Index Material"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA)); - te->name= "Color"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE)); - te->name= "Diffuse"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC)); - te->name= "Specular"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW)); - te->name= "Shadow"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO)); - te->name= "AO"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT)); - te->name= "Reflection"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT)); - te->name= "Refraction"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT)); - te->name= "Indirect"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT)); - te->name= "Environment"; - te->directdata= &srl->passflag; - - te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT)); - te->name= "Emit"; - te->directdata= &srl->passflag; -} - -#undef LOG2I - -/* special handling of hierarchical non-lib data */ -static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, - TreeElement *parent, int *a) -{ - TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); - - (*a)++; - te->name= curBone->name; - te->directdata= curBone; - - for(curBone= curBone->childbase.first; curBone; curBone=curBone->next) { - outliner_add_bone(soops, &te->subtree, id, curBone, te, a); - } -} - -static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te) -{ - SceneRenderLayer *srl; - TreeElement *tenla= outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0); - int a; - - tenla->name= "RenderLayers"; - for(a=0, srl= sce->r.layers.first; srl; srl= srl->next, a++) { - TreeElement *tenlay= outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); - tenlay->name= srl->name; - tenlay->directdata= &srl->passflag; - - if(srl->light_override) - outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0); - if(srl->mat_override) - outliner_add_element(soops, &tenlay->subtree, srl->mat_override, tenlay, TSE_LINKED_MAT, 0); - - outliner_add_passes(soops, tenlay, &sce->id, srl); - } - - outliner_add_element(soops, lb, sce->world, te, 0, 0); -} - -static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, - TreeElement *parent, short type, short index) -{ - TreeElement *te; - TreeStoreElem *tselem; - ID *id= idv; - int a = 0; - - if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { - id= ((PointerRNA*)idv)->id.data; - if(!id) id= ((PointerRNA*)idv)->data; - } - - if(id==NULL) return NULL; - - te= MEM_callocN(sizeof(TreeElement), "tree elem"); - /* add to the visual tree */ - BLI_addtail(lb, te); - /* add to the storage */ - check_persistant(soops, te, id, type, index); - tselem= TREESTORE(te); - - te->parent= parent; - te->index= index; // for data arays - if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)); - else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)); - else if(type==TSE_ANIM_DATA); - else { - te->name= id->name+2; // default, can be overridden by Library or non-ID data - te->idcode= GS(id->name); - } - - if(type==0) { - - /* tuck pointer back in object, to construct hierarchy */ - if(GS(id->name)==ID_OB) id->newid= (ID *)te; - - /* expand specific data always */ - switch(GS(id->name)) { - case ID_LI: - te->name= ((Library *)id)->name; - break; - case ID_SCE: - outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te); - break; - case ID_OB: - { - Object *ob= (Object *)id; - - outliner_add_element(soops, &te->subtree, ob->adt, te, TSE_ANIM_DATA, 0); - outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this - - if(ob->proxy && ob->id.lib==NULL) - outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0); - - outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0); - - if(ob->pose) { - bArmature *arm= ob->data; - bPoseChannel *pchan; - TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0); - - tenla->name= "Pose"; - - if(arm->edbo==NULL && (ob->mode & OB_MODE_POSE)) { // channels undefined in editmode, but we want the 'tenla' pose icon itself - int a= 0, const_index= 1000; /* ensure unique id for bone constraints */ - - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); - ten->name= pchan->name; - ten->directdata= pchan; - pchan->prev= (bPoseChannel *)ten; - - if(pchan->constraints.first) { - //Object *target; - bConstraint *con; - TreeElement *ten1; - TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); - //char *str; - - tenla1->name= "Constraints"; - for(con= pchan->constraints.first; con; con= con->next, const_index++) { - ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index); -#if 0 /* disabled as it needs to be reworked for recoded constraints system */ - target= get_constraint_target(con, &str); - if(str && str[0]) ten1->name= str; - else if(target) ten1->name= target->id.name+2; - else ten1->name= con->name; -#endif - ten1->name= con->name; - ten1->directdata= con; - /* possible add all other types links? */ - } - } - } - /* make hierarchy */ - ten= tenla->subtree.first; - while(ten) { - TreeElement *nten= ten->next, *par; - tselem= TREESTORE(ten); - if(tselem->type==TSE_POSE_CHANNEL) { - pchan= (bPoseChannel *)ten->directdata; - if(pchan->parent) { - BLI_remlink(&tenla->subtree, ten); - par= (TreeElement *)pchan->parent->prev; - BLI_addtail(&par->subtree, ten); - ten->parent= par; - } - } - ten= nten; - } - /* restore prev pointers */ - pchan= ob->pose->chanbase.first; - if(pchan) pchan->prev= NULL; - for(; pchan; pchan= pchan->next) { - if(pchan->next) pchan->next->prev= pchan; - } - } - - /* Pose Groups */ - if(ob->pose->agroups.first) { - bActionGroup *agrp; - TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0); - int a= 0; - - tenla->name= "Bone Groups"; - for (agrp=ob->pose->agroups.first; agrp; agrp=agrp->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSEGRP, a); - ten->name= agrp->name; - ten->directdata= agrp; - } - } - } - - for(a=0; a<ob->totcol; a++) - outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a); - - if(ob->constraints.first) { - //Object *target; - bConstraint *con; - TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); - int a= 0; - //char *str; - - tenla->name= "Constraints"; - for(con= ob->constraints.first; con; con= con->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); -#if 0 /* disabled due to constraints system targets recode... code here needs review */ - target= get_constraint_target(con, &str); - if(str && str[0]) ten->name= str; - else if(target) ten->name= target->id.name+2; - else ten->name= con->name; -#endif - ten->name= con->name; - ten->directdata= con; - /* possible add all other types links? */ - } - } - - if(ob->modifiers.first) { - ModifierData *md; - TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); - int index; - - temod->name = "Modifiers"; - 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); - } else if (md->type==eModifierType_Curve) { - outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_LINKED_OB, 0); - } else if (md->type==eModifierType_Armature) { - outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_LINKED_OB, 0); - } else if (md->type==eModifierType_Hook) { - outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_LINKED_OB, 0); - } else if (md->type==eModifierType_ParticleSystem) { - TreeElement *ten; - ParticleSystem *psys= ((ParticleSystemModifierData*) md)->psys; - - ten = outliner_add_element(soops, &te->subtree, ob, te, TSE_LINKED_PSYS, 0); - ten->directdata = psys; - ten->name = psys->part->id.name+2; - } - } - } - if(ob->defbase.first) { - bDeformGroup *defgroup; - TreeElement *ten; - TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0); - int a= 0; - - tenla->name= "Vertex Groups"; - for (defgroup=ob->defbase.first; defgroup; defgroup=defgroup->next, a++) { - ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a); - ten->name= defgroup->name; - ten->directdata= defgroup; - } - } - - if(ob->dup_group) - outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0); - - } - break; - case ID_ME: - { - Mesh *me= (Mesh *)id; - - //outliner_add_element(soops, &te->subtree, me->adt, te, TSE_ANIM_DATA, 0); - - outliner_add_element(soops, &te->subtree, me->key, te, 0, 0); - for(a=0; a<me->totcol; a++) - outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a); - /* could do tfaces with image links, but the images are not grouped nicely. - would require going over all tfaces, sort images in use. etc... */ - } - break; - case ID_CU: - { - Curve *cu= (Curve *)id; - - outliner_add_element(soops, &te->subtree, cu->adt, te, TSE_ANIM_DATA, 0); - - for(a=0; a<cu->totcol; a++) - outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a); - } - break; - case ID_MB: - { - MetaBall *mb= (MetaBall *)id; - for(a=0; a<mb->totcol; a++) - outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a); - } - break; - case ID_MA: - { - Material *ma= (Material *)id; - - outliner_add_element(soops, &te->subtree, ma->adt, te, TSE_ANIM_DATA, 0); - - for(a=0; a<MAX_MTEX; a++) { - if(ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); - } - } - break; - case ID_TE: - { - Tex *tex= (Tex *)id; - - outliner_add_element(soops, &te->subtree, tex->adt, te, TSE_ANIM_DATA, 0); - outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0); - } - break; - case ID_CA: - { - Camera *ca= (Camera *)id; - outliner_add_element(soops, &te->subtree, ca->adt, te, TSE_ANIM_DATA, 0); - } - break; - case ID_LA: - { - Lamp *la= (Lamp *)id; - - outliner_add_element(soops, &te->subtree, la->adt, te, TSE_ANIM_DATA, 0); - - for(a=0; a<MAX_MTEX; a++) { - if(la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); - } - } - break; - case ID_WO: - { - World *wrld= (World *)id; - - outliner_add_element(soops, &te->subtree, wrld->adt, te, TSE_ANIM_DATA, 0); - - for(a=0; a<MAX_MTEX; a++) { - if(wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); - } - } - break; - case ID_KE: - { - Key *key= (Key *)id; - - outliner_add_element(soops, &te->subtree, key->adt, te, TSE_ANIM_DATA, 0); - } - break; - case ID_AC: - { - // XXX do we want to be exposing the F-Curves here? - //bAction *act= (bAction *)id; - } - break; - case ID_AR: - { - bArmature *arm= (bArmature *)id; - int a= 0; - - if(arm->edbo) { - EditBone *ebone; - TreeElement *ten; - - for (ebone = arm->edbo->first; ebone; ebone=ebone->next, a++) { - ten= outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a); - ten->directdata= ebone; - ten->name= ebone->name; - ebone->temp= ten; - } - /* make hierarchy */ - ten= te->subtree.first; - while(ten) { - TreeElement *nten= ten->next, *par; - ebone= (EditBone *)ten->directdata; - if(ebone->parent) { - BLI_remlink(&te->subtree, ten); - par= ebone->parent->temp; - BLI_addtail(&par->subtree, ten); - ten->parent= par; - } - ten= nten; - } - } - else { - /* do not extend Armature when we have posemode */ - tselem= TREESTORE(te->parent); - if( GS(tselem->id->name)==ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE); - else { - Bone *curBone; - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - outliner_add_bone(soops, &te->subtree, id, curBone, te, &a); - } - } - } - } - break; - } - } - else if(type==TSE_ANIM_DATA) { - AnimData *adt= (AnimData *)idv; - - /* this element's info */ - te->name= "Animation"; - - /* Action */ - outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0); - - /* Drivers */ - if (adt->drivers.first) { - TreeElement *ted= outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0); - ID *lastadded= NULL; - FCurve *fcu; - - ted->name= "Drivers"; - - for (fcu= adt->drivers.first; fcu; fcu= fcu->next) { - if (fcu->driver && fcu->driver->variables.first) { - ChannelDriver *driver= fcu->driver; - DriverVar *dvar; - - for (dvar= driver->variables.first; dvar; dvar= dvar->next) { - /* loop over all targets used here */ - DRIVER_TARGETS_USED_LOOPER(dvar) - { - if (lastadded != dtar->id) { - // XXX this lastadded check is rather lame, and also fails quite badly... - outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0); - lastadded= dtar->id; - } - } - DRIVER_TARGETS_LOOPER_END - } - } - } - } - - /* NLA Data */ - if (adt->nla_tracks.first) { - TreeElement *tenla= outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0); - NlaTrack *nlt; - int a= 0; - - tenla->name= "NLA Tracks"; - - for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { - TreeElement *tenlt= outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a); - NlaStrip *strip; - TreeElement *ten; - int b= 0; - - tenlt->name= nlt->name; - - for (strip=nlt->strips.first; strip; strip=strip->next, b++) { - ten= outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b); - if(ten) ten->directdata= strip; - } - } - } - } - else if(type==TSE_SEQUENCE) { - Sequence *seq= (Sequence*) idv; - Sequence *p; - - /* - * The idcode is a little hack, but the outliner - * only check te->idcode if te->type is equal to zero, - * so this is "safe". - */ - te->idcode= seq->type; - te->directdata= seq; - - if(seq->type<7) { - /* - * This work like the sequence. - * If the sequence have a name (not default name) - * show it, in other case put the filename. - */ - if(strcmp(seq->name, "SQ")) - te->name= seq->name; - else { - if((seq->strip) && (seq->strip->stripdata)) - te->name= seq->strip->stripdata->name; - else - te->name= "SQ None"; - } - - if(seq->type==SEQ_META) { - te->name= "Meta Strip"; - p= seq->seqbase.first; - while(p) { - outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); - p= p->next; - } - } - else - outliner_add_element(soops, &te->subtree, (void*)seq->strip, te, TSE_SEQ_STRIP, index); - } - else - te->name= "Effect"; - } - else if(type==TSE_SEQ_STRIP) { - Strip *strip= (Strip *)idv; - - if(strip->dir) - te->name= strip->dir; - else - te->name= "Strip None"; - te->directdata= strip; - } - else if(type==TSE_SEQUENCE_DUP) { - Sequence *seq= (Sequence*)idv; - - te->idcode= seq->type; - te->directdata= seq; - te->name= seq->strip->stripdata->name; - } - else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { - PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv; - PropertyRNA *prop, *iterprop; - PropertyType proptype; - int a, tot; - - /* we do lazy build, for speed and to avoid infinite recusion */ - - if(ptr->data == NULL) { - te->name= "(empty)"; - } - else if(type == TSE_RNA_STRUCT) { - /* struct */ - te->name= RNA_struct_name_get_alloc(ptr, NULL, 0); - - if(te->name) - te->flag |= TE_FREE_NAME; - else - te->name= (char*)RNA_struct_ui_name(ptr->type); - - iterprop= RNA_struct_iterator_property(ptr->type); - tot= RNA_property_collection_length(ptr, iterprop); - - /* auto open these cases */ - if(!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER) - if(!tselem->used) - tselem->flag &= ~TSE_CLOSED; - - if(!(tselem->flag & TSE_CLOSED)) { - for(a=0; a<tot; a++) - outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a); - } - else if(tot) - te->flag |= TE_LAZY_CLOSED; - - te->rnaptr= *ptr; - } - else if(type == TSE_RNA_PROPERTY) { - /* property */ - iterprop= RNA_struct_iterator_property(ptr->type); - RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr); - - prop= propptr.data; - proptype= RNA_property_type(prop); - - te->name= (char*)RNA_property_ui_name(prop); - te->directdata= prop; - te->rnaptr= *ptr; - - if(proptype == PROP_POINTER) { - pptr= RNA_property_pointer_get(ptr, prop); - - if(pptr.data) { - if(!(tselem->flag & TSE_CLOSED)) - outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); - else - te->flag |= TE_LAZY_CLOSED; - } - } - else if(proptype == PROP_COLLECTION) { - tot= RNA_property_collection_length(ptr, prop); - - if(!(tselem->flag & TSE_CLOSED)) { - for(a=0; a<tot; a++) { - RNA_property_collection_lookup_int(ptr, prop, a, &pptr); - outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); - } - } - else if(tot) - te->flag |= TE_LAZY_CLOSED; - } - else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { - tot= RNA_property_array_length(ptr, prop); - - if(!(tselem->flag & TSE_CLOSED)) { - for(a=0; a<tot; a++) - outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a); - } - else if(tot) - te->flag |= TE_LAZY_CLOSED; - } - } - else if(type == TSE_RNA_ARRAY_ELEM) { - char c; - - prop= parent->directdata; - - te->directdata= prop; - te->rnaptr= *ptr; - te->index= index; - - c= RNA_property_array_item_char(prop, index); - - te->name= MEM_callocN(sizeof(char)*20, "OutlinerRNAArrayName"); - if(c) sprintf((char *)te->name, " %c", c); - else sprintf((char *)te->name, " %d", index+1); - te->flag |= TE_FREE_NAME; - } - } - else if(type == TSE_KEYMAP) { - wmKeyMap *km= (wmKeyMap *)idv; - wmKeyMapItem *kmi; - char opname[OP_MAX_TYPENAME]; - - te->directdata= idv; - te->name= km->idname; - - if(!(tselem->flag & TSE_CLOSED)) { - a= 0; - - for (kmi= km->items.first; kmi; kmi= kmi->next, a++) { - const char *key= WM_key_event_string(kmi->type); - - if(key[0]) { - wmOperatorType *ot= NULL; - - if(kmi->propvalue); - else ot= WM_operatortype_find(kmi->idname, 0); - - if(ot || kmi->propvalue) { - TreeElement *ten= outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); - - ten->directdata= kmi; - - if(kmi->propvalue) { - ten->name= "Modal map, not yet"; - } - else { - WM_operator_py_idname(opname, ot->idname); - ten->name= BLI_strdup(opname); - ten->flag |= TE_FREE_NAME; - } - } - } - } - } - else - te->flag |= TE_LAZY_CLOSED; - } - - return te; -} - -static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) -{ - TreeElement *te, *ten, *tep; - TreeStoreElem *tselem; - - /* build hierarchy */ - // XXX also, set extents here... - te= lb->first; - while(te) { - ten= te->next; - tselem= TREESTORE(te); - - if(tselem->type==0 && te->idcode==ID_OB) { - Object *ob= (Object *)tselem->id; - if(ob->parent && ob->parent->id.newid) { - BLI_remlink(lb, te); - tep= (TreeElement *)ob->parent->id.newid; - BLI_addtail(&tep->subtree, te); - // set correct parent pointers - for(te=tep->subtree.first; te; te= te->next) te->parent= tep; - } - } - te= ten; - } -} - -/* Helped function to put duplicate sequence in the same tree. */ -static int need_add_seq_dup(Sequence *seq) -{ - Sequence *p; - - if((!seq->strip) || (!seq->strip->stripdata) || (!seq->strip->stripdata->name)) - return(1); - - /* - * First check backward, if we found a duplicate - * sequence before this, don't need it, just return. - */ - p= seq->prev; - while(p) { - if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { - p= p->prev; - continue; - } - - if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) - return(2); - p= p->prev; - } - - p= seq->next; - while(p) { - if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { - p= p->next; - continue; - } - - if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) - return(0); - p= p->next; - } - return(1); -} - -static void add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index) -{ - TreeElement *ch; - Sequence *p; - - p= seq; - while(p) { - if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { - p= p->next; - continue; - } - - if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) - ch= outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); - p= p->next; - } -} - -static int outliner_filter_has_name(TreeElement *te, const char *name, int flags) -{ -#if 0 - int found= 0; - - /* determine if match */ - if (flags & SO_FIND_CASE_SENSITIVE) { - if (flags & SO_FIND_COMPLETE) - found= strcmp(te->name, name) == 0; - else - found= strstr(te->name, name) != NULL; - } - else { - if (flags & SO_FIND_COMPLETE) - found= BLI_strcasecmp(te->name, name) == 0; - else - found= BLI_strcasestr(te->name, name) != NULL; - } -#else - - int fn_flag= 0; - int found= 0; - - if ((flags & SO_FIND_CASE_SENSITIVE) == 0) - fn_flag |= FNM_CASEFOLD; - - if (flags & SO_FIND_COMPLETE) { - found= fnmatch(name, te->name, fn_flag)==0; - } - else { - char fn_name[sizeof(((struct SpaceOops *)NULL)->search_string) + 2]; - sprintf(fn_name, "*%s*", name); - found= fnmatch(fn_name, te->name, fn_flag)==0; - } - return found; -#endif -} - -static int outliner_filter_tree(SpaceOops *soops, ListBase *lb) -{ - TreeElement *te, *ten; - TreeStoreElem *tselem; - - /* although we don't have any search string, we return TRUE - * since the entire tree is ok then... - */ - if (soops->search_string[0]==0) - return 1; - - for (te= lb->first; te; te= ten) { - ten= te->next; - - if (0==outliner_filter_has_name(te, soops->search_string, soops->search_flags)) { - /* item isn't something we're looking for, but... - * - if the subtree is expanded, check if there are any matches that can be easily found - * so that searching for "cu" in the default scene will still match the Cube - * - otherwise, we can't see within the subtree and the item doesn't match, - * so these can be safely ignored (i.e. the subtree can get freed) - */ - tselem= TREESTORE(te); - - if ((tselem->flag & TSE_CLOSED) || outliner_filter_tree(soops, &te->subtree)==0) { - outliner_free_tree(&te->subtree); - BLI_remlink(lb, te); - - if(te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name); - MEM_freeN(te); - } - } - else { - /* filter subtree too */ - outliner_filter_tree(soops, &te->subtree); - } - } - - /* if there are still items in the list, that means that there were still some matches */ - return (lb->first != NULL); -} - - -static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) -{ - Base *base; - Object *ob; - TreeElement *te=NULL, *ten; - TreeStoreElem *tselem; - int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */ - - if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW)) - return; - - outliner_free_tree(&soops->tree); - outliner_storage_cleanup(soops); - - /* clear ob id.new flags */ - for(ob= mainvar->object.first; ob; ob= ob->id.next) ob->id.newid= NULL; - - /* options */ - if(soops->outlinevis == SO_LIBRARIES) { - Library *lib; - - for(lib= mainvar->library.first; lib; lib= lib->id.next) { - ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); - lib->id.newid= (ID *)ten; - } - /* make hierarchy */ - ten= soops->tree.first; - while(ten) { - TreeElement *nten= ten->next, *par; - tselem= TREESTORE(ten); - lib= (Library *)tselem->id; - if(lib->parent) { - BLI_remlink(&soops->tree, ten); - par= (TreeElement *)lib->parent->id.newid; - BLI_addtail(&par->subtree, ten); - ten->parent= par; - } - ten= nten; - } - /* restore newid pointers */ - for(lib= mainvar->library.first; lib; lib= lib->id.next) - lib->id.newid= NULL; - - } - else if(soops->outlinevis == SO_ALL_SCENES) { - Scene *sce; - for(sce= mainvar->scene.first; sce; sce= sce->id.next) { - te= outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0); - tselem= TREESTORE(te); - if(sce==scene && show_opened) - tselem->flag &= ~TSE_CLOSED; - - for(base= sce->base.first; base; base= base->next) { - ten= outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); - ten->directdata= base; - } - outliner_make_hierarchy(soops, &te->subtree); - /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ - for(base= sce->base.first; base; base= base->next) base->object->id.newid= NULL; - } - } - else if(soops->outlinevis == SO_CUR_SCENE) { - - outliner_add_scene_contents(soops, &soops->tree, scene, NULL); - - for(base= scene->base.first; base; base= base->next) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); - ten->directdata= base; - } - outliner_make_hierarchy(soops, &soops->tree); - } - else if(soops->outlinevis == SO_VISIBLE) { - for(base= scene->base.first; base; base= base->next) { - if(base->lay & scene->lay) - outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); - } - outliner_make_hierarchy(soops, &soops->tree); - } - else if(soops->outlinevis == SO_GROUPS) { - Group *group; - GroupObject *go; - - for(group= mainvar->group.first; group; group= group->id.next) { - if(group->gobject.first) { - te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0); - - for(go= group->gobject.first; go; go= go->next) { - ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); - ten->directdata= NULL; /* eh, why? */ - } - outliner_make_hierarchy(soops, &te->subtree); - /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ - for(go= group->gobject.first; go; go= go->next) go->ob->id.newid= NULL; - } - } - } - else if(soops->outlinevis == SO_SAME_TYPE) { - Object *ob= OBACT; - if(ob) { - for(base= scene->base.first; base; base= base->next) { - if(base->object->type==ob->type) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); - ten->directdata= base; - } - } - outliner_make_hierarchy(soops, &soops->tree); - } - } - else if(soops->outlinevis == SO_SELECTED) { - for(base= scene->base.first; base; base= base->next) { - if(base->lay & scene->lay) { - if(base==BASACT || (base->flag & SELECT)) { - ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); - ten->directdata= base; - } - } - } - outliner_make_hierarchy(soops, &soops->tree); - } - else if(soops->outlinevis==SO_SEQUENCE) { - Sequence *seq; - Editing *ed= seq_give_editing(scene, FALSE); - int op; - - if(ed==NULL) - return; - - seq= ed->seqbasep->first; - if(!seq) - return; - - while(seq) { - op= need_add_seq_dup(seq); - if(op==1) - ten= outliner_add_element(soops, &soops->tree, (void*)seq, NULL, TSE_SEQUENCE, 0); - else if(op==0) { - ten= outliner_add_element(soops, &soops->tree, (void*)seq, NULL, TSE_SEQUENCE_DUP, 0); - add_seq_dup(soops, seq, ten, 0); - } - seq= seq->next; - } - } - else if(soops->outlinevis==SO_DATABLOCKS) { - PointerRNA mainptr; - - RNA_main_pointer_create(mainvar, &mainptr); - - ten= outliner_add_element(soops, &soops->tree, (void*)&mainptr, NULL, TSE_RNA_STRUCT, -1); - - if(show_opened) { - tselem= TREESTORE(ten); - tselem->flag &= ~TSE_CLOSED; - } - } - else if(soops->outlinevis==SO_USERDEF) { - PointerRNA userdefptr; - - RNA_pointer_create(NULL, &RNA_UserPreferences, &U, &userdefptr); - - ten= outliner_add_element(soops, &soops->tree, (void*)&userdefptr, NULL, TSE_RNA_STRUCT, -1); - - if(show_opened) { - tselem= TREESTORE(ten); - tselem->flag &= ~TSE_CLOSED; - } - } - else if(soops->outlinevis==SO_KEYMAP) { - wmWindowManager *wm= mainvar->wm.first; - wmKeyMap *km; - - for(km= wm->defaultconf->keymaps.first; km; km= km->next) { - ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0); - } - } - else { - ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); - if(ten) ten->directdata= BASACT; - } - - outliner_sort(soops, &soops->tree); - outliner_filter_tree(soops, &soops->tree); -} - -/* **************** INTERACTIVE ************* */ - - -static int outliner_scroll_page_exec(bContext *C, wmOperator *op) -{ - ARegion *ar= CTX_wm_region(C); - int dy= ar->v2d.mask.ymax - ar->v2d.mask.ymin; - int up= 0; - - if(RNA_boolean_get(op->ptr, "up")) - up= 1; - - if(up == 0) dy= -dy; - ar->v2d.cur.ymin+= dy; - ar->v2d.cur.ymax+= dy; - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_scroll_page(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Scroll Page"; - ot->idname= "OUTLINER_OT_scroll_page"; - ot->description= "Scroll page up or down"; - - /* callbacks */ - ot->exec= outliner_scroll_page_exec; - ot->poll= ED_operator_outliner_active; - - /* properties */ - RNA_def_boolean(ot->srna, "up", 0, "Up", "Scroll up one page."); -} - - -static int outliner_count_levels(SpaceOops *soops, ListBase *lb, int curlevel) -{ - TreeElement *te; - int level=curlevel, lev; - - for(te= lb->first; te; te= te->next) { - - lev= outliner_count_levels(soops, &te->subtree, curlevel+1); - if(lev>level) level= lev; - } - return level; -} - -static int outliner_has_one_flag(SpaceOops *soops, ListBase *lb, short flag, short curlevel) -{ - TreeElement *te; - TreeStoreElem *tselem; - int level; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->flag & flag) return curlevel; - - level= outliner_has_one_flag(soops, &te->subtree, flag, curlevel+1); - if(level) return level; - } - return 0; -} - -static void outliner_set_flag(SpaceOops *soops, ListBase *lb, short flag, short set) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(set==0) tselem->flag &= ~flag; - else tselem->flag |= flag; - outliner_set_flag(soops, &te->subtree, flag, set); - } -} - -/* --- */ - -/* same check needed for both object operation and restrict column button func - * return 0 when in edit mode (cannot restrict view or select) - * otherwise return 1 */ -static int common_restrict_check(bContext *C, Object *ob) -{ - /* Don't allow hide an object in edit mode, - * check the bug #22153 and #21609, #23977 - */ - Object *obedit= CTX_data_edit_object(C); - if (obedit && obedit == ob) { - /* found object is hidden, reset */ - if (ob->restrictflag & OB_RESTRICT_VIEW) - ob->restrictflag &= ~OB_RESTRICT_VIEW; - /* found object is unselectable, reset */ - if (ob->restrictflag & OB_RESTRICT_SELECT) - ob->restrictflag &= ~OB_RESTRICT_SELECT; - return 0; - } - - return 1; -} - -static void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - Object *ob = (Object *)tselem->id; - - /* add check for edit mode */ - if(!common_restrict_check(C, ob)) return; - - if(base || (base= object_in_scene(ob, scene))) { - if((base->object->restrictflag ^= OB_RESTRICT_VIEW)) { - ED_base_object_select(base, BA_DESELECT); - } - } -} - -static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); - - WM_event_add_notifier(C, NC_SCENE|ND_OB_VISIBLE, scene); - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_visibility_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Visibility"; - ot->idname= "OUTLINER_OT_visibility_toggle"; - ot->description= "Toggle the visibility of selected items"; - - /* callbacks */ - ot->exec= outliner_toggle_visibility_exec; - ot->poll= ED_operator_outliner_active_no_editobject; - - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* --- */ - -static void object_toggle_selectability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - - if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); - if(base) { - base->object->restrictflag^=OB_RESTRICT_SELECT; - } -} - -static int outliner_toggle_selectability_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_selectability_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Selectability"; - ot->idname= "OUTLINER_OT_selectability_toggle"; - ot->description= "Toggle the selectability"; - - /* callbacks */ - ot->exec= outliner_toggle_selectability_exec; - ot->poll= ED_operator_outliner_active_no_editobject; - - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static void object_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - - if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); - if(base) { - base->object->restrictflag^=OB_RESTRICT_RENDER; - } -} - -static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_renderability_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Renderability"; - ot->idname= "OUTLINER_OT_renderability_toggle"; - ot->description= "Toggle the renderability of selected items"; - - /* callbacks */ - ot->exec= outliner_toggle_renderability_exec; - ot->poll= ED_operator_outliner_active; - - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* --- */ - -static int outliner_toggle_expanded_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - ARegion *ar= CTX_wm_region(C); - - if (outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1)) - outliner_set_flag(soops, &soops->tree, TSE_CLOSED, 0); - else - outliner_set_flag(soops, &soops->tree, TSE_CLOSED, 1); - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_expanded_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Expand/Collapse All"; - ot->idname= "OUTLINER_OT_expanded_toggle"; - ot->description= "Expand/Collapse all items"; - - /* callbacks */ - ot->exec= outliner_toggle_expanded_exec; - ot->poll= ED_operator_outliner_active; - - /* no undo or registry, UI option */ -} - -/* --- */ - -static int outliner_toggle_selected_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - ARegion *ar= CTX_wm_region(C); - Scene *scene= CTX_data_scene(C); - - if (outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1)) - outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); - else - outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 1); - - soops->storeflag |= SO_TREESTORE_REDRAW; - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_selected_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Toggle Selected"; - ot->idname= "OUTLINER_OT_selected_toggle"; - ot->description= "Toggle the Outliner selection of items"; - - /* callbacks */ - ot->exec= outliner_toggle_selected_exec; - ot->poll= ED_operator_outliner_active; - - /* no undo or registry, UI option */ -} - -/* --- */ - -/* helper function for Show/Hide one level operator */ -static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curlevel, int level, int open) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - - if(open) { - if(curlevel<=level) tselem->flag &= ~TSE_CLOSED; - } - else { - if(curlevel>=level) tselem->flag |= TSE_CLOSED; - } - - outliner_openclose_level(soops, &te->subtree, curlevel+1, level, open); - } -} - -static int outliner_one_level_exec(bContext *C, wmOperator *op) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - ARegion *ar= CTX_wm_region(C); - int add= RNA_boolean_get(op->ptr, "open"); - int level; - - level= outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1); - if(add==1) { - if(level) outliner_openclose_level(soops, &soops->tree, 1, level, 1); - } - else { - if(level==0) level= outliner_count_levels(soops, &soops->tree, 0); - if(level) outliner_openclose_level(soops, &soops->tree, 1, level-1, 0); - } - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_show_one_level(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Show/Hide One Level"; - ot->idname= "OUTLINER_OT_show_one_level"; - ot->description= "Expand/collapse all entries by one level"; - - /* callbacks */ - ot->exec= outliner_one_level_exec; - ot->poll= ED_operator_outliner_active; - - /* no undo or registry, UI option */ - - /* properties */ - RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep."); -} - -/* This is not used anywhere at the moment */ -#if 0 -/* return 1 when levels were opened */ -static int outliner_open_back(SpaceOops *soops, TreeElement *te) -{ - TreeStoreElem *tselem; - int retval= 0; - - for (te= te->parent; te; te= te->parent) { - tselem= TREESTORE(te); - if (tselem->flag & TSE_CLOSED) { - tselem->flag &= ~TSE_CLOSED; - retval= 1; - } - } - return retval; -} - -static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for (te= lb->first; te; te= te->next) { - /* check if this tree-element was the one we're seeking */ - if (te == teFind) { - *found= 1; - return; - } - - /* try to see if sub-tree contains it then */ - outliner_open_reveal(soops, &te->subtree, teFind, found); - if (*found) { - tselem= TREESTORE(te); - if (tselem->flag & TSE_CLOSED) - tselem->flag &= ~TSE_CLOSED; - return; - } - } -} -#endif - -// XXX just use View2D ops for this? -static void outliner_page_up_down(Scene *UNUSED(scene), ARegion *ar, SpaceOops *soops, int up) -{ - int dy= ar->v2d.mask.ymax-ar->v2d.mask.ymin; - - if(up == -1) dy= -dy; - ar->v2d.cur.ymin+= dy; - ar->v2d.cur.ymax+= dy; - - soops->storeflag |= SO_TREESTORE_REDRAW; -} - -/* **** do clicks on items ******* */ - -static int tree_element_active_renderlayer(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set) -{ - Scene *sce; - - /* paranoia check */ - if(te->idcode!=ID_SCE) - return 0; - sce= (Scene *)tselem->id; - - if(set) { - sce->r.actlay= tselem->nr; - WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, sce); - } - else { - return sce->r.actlay==tselem->nr; - } - return 0; -} - -static void tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - TreeStoreElem *tselem= TREESTORE(te); - Scene *sce; - Base *base; - Object *ob= NULL; - - /* if id is not object, we search back */ - if(te->idcode==ID_OB) ob= (Object *)tselem->id; - else { - ob= (Object *)outliner_search_back(soops, te, ID_OB); - if(ob==OBACT) return; - } - if(ob==NULL) return; - - sce= (Scene *)outliner_search_back(soops, te, ID_SCE); - if(sce && scene != sce) { - ED_screen_set_scene(C, sce); - } - - /* find associated base in current scene */ - base= object_in_scene(ob, scene); - - if(base) { - if(set==2) { - /* swap select */ - if(base->flag & SELECT) - ED_base_object_select(base, BA_DESELECT); - else - ED_base_object_select(base, BA_SELECT); - } - else { - /* deleselect all */ - scene_deselect_all(scene); - ED_base_object_select(base, BA_SELECT); - } - if(C) { - ED_base_object_activate(C, base); /* adds notifier */ - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - } - - if(ob!=scene->obedit) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); -} - -static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - TreeElement *tes; - Object *ob; - - /* we search for the object parent */ - ob= (Object *)outliner_search_back(soops, te, ID_OB); - // note: ob->matbits can be NULL when a local object points to a library mesh. - if(ob==NULL || ob!=OBACT || ob->matbits==NULL) return 0; // just paranoia - - /* searching in ob mat array? */ - tes= te->parent; - if(tes->idcode==ID_OB) { - if(set) { - ob->actcol= te->index+1; - ob->matbits[te->index]= 1; // make ob material active too - ob->colbits |= (1<<te->index); - } - else { - if(ob->actcol == te->index+1) - if(ob->matbits[te->index]) return 1; - } - } - /* or we search for obdata material */ - else { - if(set) { - ob->actcol= te->index+1; - ob->matbits[te->index]= 0; // make obdata material active too - ob->colbits &= ~(1<<te->index); - } - else { - if(ob->actcol == te->index+1) - if(ob->matbits[te->index]==0) return 1; - } - } - if(set) { - WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, NULL); - } - return 0; -} - -static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - TreeElement *tep; - TreeStoreElem /* *tselem,*/ *tselemp; - Object *ob=OBACT; - SpaceButs *sbuts=NULL; - - if(ob==NULL) return 0; // no active object - - /*tselem= TREESTORE(te);*/ /*UNUSED*/ - - /* find buttons area (note, this is undefined really still, needs recode in blender) */ - /* XXX removed finding sbuts */ - - /* where is texture linked to? */ - tep= te->parent; - tselemp= TREESTORE(tep); - - if(tep->idcode==ID_WO) { - World *wrld= (World *)tselemp->id; - - if(set) { - if(sbuts) { - // XXX sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom= 1; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - wrld->texact= te->index; - } - else if(tselemp->id == (ID *)(scene->world)) { - if(wrld->texact==te->index) return 1; - } - } - else if(tep->idcode==ID_LA) { - Lamp *la= (Lamp *)tselemp->id; - if(set) { - if(sbuts) { - // XXX sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom= 2; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - la->texact= te->index; - } - else { - if(tselemp->id == ob->data) { - if(la->texact==te->index) return 1; - } - } - } - else if(tep->idcode==ID_MA) { - Material *ma= (Material *)tselemp->id; - if(set) { - if(sbuts) { - //sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom= 0; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - ma->texact= (char)te->index; - - /* also set active material */ - ob->actcol= tep->index+1; - } - else if(tep->flag & TE_ACTIVE) { // this is active material - if(ma->texact==te->index) return 1; - } - } - - if(set) - WM_event_add_notifier(C, NC_TEXTURE, NULL); - - return 0; -} - - -static int tree_element_active_lamp(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - Object *ob; - - /* we search for the object parent */ - ob= (Object *)outliner_search_back(soops, te, ID_OB); - if(ob==NULL || ob!=OBACT) return 0; // just paranoia - - if(set) { -// XXX extern_set_butspace(F5KEY, 0); - } - else return 1; - - return 0; -} - -static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - Object *ob= (Object *)outliner_search_back(soops, te, ID_OB); - - if(set) - return 0; - - return scene->camera == ob; -} - -static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - TreeElement *tep; - TreeStoreElem *tselem=NULL; - Scene *sce=NULL; - - tep= te->parent; - if(tep) { - tselem= TREESTORE(tep); - sce= (Scene *)tselem->id; - } - - if(set) { // make new scene active - if(sce && scene != sce) { - ED_screen_set_scene(C, sce); - } - } - - if(tep==NULL || tselem->id == (ID *)scene) { - if(set) { -// XXX extern_set_butspace(F8KEY, 0); - } - else { - return 1; - } - } - return 0; -} - -static int tree_element_active_defgroup(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) -{ - Object *ob; - - /* id in tselem is object */ - ob= (Object *)tselem->id; - if(set) { - ob->actdef= te->index+1; - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); - } - else { - if(ob==OBACT) - if(ob->actdef== te->index+1) return 1; - } - return 0; -} - -static int tree_element_active_posegroup(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) -{ - Object *ob= (Object *)tselem->id; - - if(set) { - if (ob->pose) { - ob->pose->active_group= te->index+1; - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - } - } - else { - if(ob==OBACT && ob->pose) { - if (ob->pose->active_group== te->index+1) return 1; - } - } - return 0; -} - -static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) -{ - Object *ob= (Object *)tselem->id; - bArmature *arm= ob->data; - bPoseChannel *pchan= te->directdata; - - if(set) { - if(!(pchan->bone->flag & BONE_HIDDEN_P)) { - - if(set==2) ED_pose_deselectall(ob, 2); // 2 = clear active tag - else ED_pose_deselectall(ob, 0); // 0 = deselect - - if(set==2 && (pchan->bone->flag & BONE_SELECTED)) { - pchan->bone->flag &= ~BONE_SELECTED; - } else { - pchan->bone->flag |= BONE_SELECTED; - arm->act_bone= pchan->bone; - } - - WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, ob); - - } - } - else { - if(ob==OBACT && ob->pose) { - if (pchan->bone->flag & BONE_SELECTED) return 1; - } - } - return 0; -} - -static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) -{ - bArmature *arm= (bArmature *)tselem->id; - Bone *bone= te->directdata; - - if(set) { - if(!(bone->flag & BONE_HIDDEN_P)) { - if(set==2) ED_pose_deselectall(OBACT, 2); // 2 is clear active tag - else ED_pose_deselectall(OBACT, 0); - - if(set==2 && (bone->flag & BONE_SELECTED)) { - bone->flag &= ~BONE_SELECTED; - } else { - bone->flag |= BONE_SELECTED; - arm->act_bone= bone; - } - - WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, OBACT); - } - } - else { - Object *ob= OBACT; - - if(ob && ob->data==arm) { - if (bone->flag & BONE_SELECTED) return 1; - } - } - return 0; -} - - -/* ebones only draw in editmode armature */ -static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature *arm, EditBone *ebone, short sel) -{ - if(sel) { - ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL; - arm->act_edbone= ebone; - // flush to parent? - if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag |= BONE_TIPSEL; - } - else { - ebone->flag &= ~(BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL); - // flush to parent? - if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag &= ~BONE_TIPSEL; - } - - WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, scene->obedit); -} -static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) -{ - bArmature *arm= scene->obedit->data; - EditBone *ebone= te->directdata; - - if(set==1) { - if(!(ebone->flag & BONE_HIDDEN_A)) { - ED_armature_deselect_all(scene->obedit, 0); // deselect - tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); - return 1; - } - } - else if (set==2) { - if(!(ebone->flag & BONE_HIDDEN_A)) { - if(!(ebone->flag & BONE_SELECTED)) { - tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); - return 1; - } - else { - /* entirely selected, so de-select */ - tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE); - return 0; - } - } - } - else if (ebone->flag & BONE_SELECTED) { - return 1; - } - return 0; -} - -static int tree_element_active_modifier(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) -{ - if(set) { - Object *ob= (Object *)tselem->id; - - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - -// XXX extern_set_butspace(F9KEY, 0); - } - - return 0; -} - -static int tree_element_active_psys(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) -{ - if(set) { - Object *ob= (Object *)tselem->id; - - WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); - -// XXX extern_set_butspace(F7KEY, 0); - } - - return 0; -} - -static int tree_element_active_constraint(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) -{ - if(set) { - Object *ob= (Object *)tselem->id; - - WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); -// XXX extern_set_butspace(F7KEY, 0); - } - - return 0; -} - -static int tree_element_active_text(bContext *UNUSED(C), Scene *UNUSED(scene), SpaceOops *UNUSED(soops), TreeElement *UNUSED(te), int UNUSED(set)) -{ - // XXX removed - return 0; -} - -/* generic call for ID data check or make/check active in UI */ -static int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) -{ - - switch(te->idcode) { - case ID_MA: - return tree_element_active_material(C, scene, soops, te, set); - case ID_WO: - return tree_element_active_world(C, scene, soops, te, set); - case ID_LA: - return tree_element_active_lamp(C, scene, soops, te, set); - case ID_TE: - return tree_element_active_texture(C, scene, soops, te, set); - case ID_TXT: - return tree_element_active_text(C, scene, soops, te, set); - case ID_CA: - return tree_element_active_camera(C, scene, soops, te, set); - } - return 0; -} - -static int tree_element_active_pose(bContext *C, Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) -{ - Object *ob= (Object *)tselem->id; - Base *base= object_in_scene(ob, scene); - - if(set) { - if(scene->obedit) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); - - if(ob->mode & OB_MODE_POSE) - ED_armature_exit_posemode(C, base); - else - ED_armature_enter_posemode(C, base); - } - else { - if(ob->mode & OB_MODE_POSE) return 1; - } - return 0; -} - -static int tree_element_active_sequence(TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) -{ - Sequence *seq= (Sequence*) te->directdata; - - if(set) { -// XXX select_single_seq(seq, 1); - } - else { - if(seq->flag & SELECT) - return(1); - } - return(0); -} - -static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) -{ - Sequence *seq, *p; - Editing *ed= seq_give_editing(scene, FALSE); - - seq= (Sequence*)te->directdata; - if(set==0) { - if(seq->flag & SELECT) - return(1); - return(0); - } - -// XXX select_single_seq(seq, 1); - p= ed->seqbasep->first; - while(p) { - if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { - p= p->next; - continue; - } - -// if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) -// XXX select_single_seq(p, 0); - p= p->next; - } - return(0); -} - -static int tree_element_active_keymap_item(bContext *UNUSED(C), TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) -{ - wmKeyMapItem *kmi= te->directdata; - - if(set==0) { - if(kmi->flag & KMI_INACTIVE) return 0; - return 1; - } - else { - kmi->flag ^= KMI_INACTIVE; - } - return 0; -} - - -/* generic call for non-id data to make/check active in UI */ -/* Context can be NULL when set==0 */ -static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set) -{ - switch(tselem->type) { - case TSE_DEFGROUP: - return tree_element_active_defgroup(C, scene, te, tselem, set); - case TSE_BONE: - return tree_element_active_bone(C, scene, te, tselem, set); - case TSE_EBONE: - return tree_element_active_ebone(C, scene, te, tselem, set); - case TSE_MODIFIER: - return tree_element_active_modifier(C, te, tselem, set); - case TSE_LINKED_OB: - if(set) tree_element_set_active_object(C, scene, soops, te, set); - else if(tselem->id==(ID *)OBACT) return 1; - break; - case TSE_LINKED_PSYS: - return tree_element_active_psys(C, scene, te, tselem, set); - case TSE_POSE_BASE: - return tree_element_active_pose(C, scene, te, tselem, set); - case TSE_POSE_CHANNEL: - return tree_element_active_posechannel(C, scene, te, tselem, set); - case TSE_CONSTRAINT: - return tree_element_active_constraint(C, te, tselem, set); - case TSE_R_LAYER: - return tree_element_active_renderlayer(C, te, tselem, set); - case TSE_POSEGRP: - return tree_element_active_posegroup(C, scene, te, tselem, set); - case TSE_SEQUENCE: - return tree_element_active_sequence(te, tselem, set); - case TSE_SEQUENCE_DUP: - return tree_element_active_sequence_dup(scene, te, tselem, set); - case TSE_KEYMAP_ITEM: - return tree_element_active_keymap_item(C, te, tselem, set); - - } - return 0; -} - -static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2]) -{ - - if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { - TreeStoreElem *tselem= TREESTORE(te); - int openclose= 0; - - /* open close icon */ - if((te->flag & TE_ICONROW)==0) { // hidden icon, no open/close - if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X) - openclose= 1; - } - - if(openclose) { - /* all below close/open? */ - if(extend) { - tselem->flag &= ~TSE_CLOSED; - outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); - } - else { - if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; - else tselem->flag |= TSE_CLOSED; - - } - - return 1; - } - /* name and first icon */ - else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { - - /* always makes active object */ - if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP) - tree_element_set_active_object(C, scene, soops, te, 1 + (extend!=0 && tselem->type==0)); - - if(tselem->type==0) { // the lib blocks - /* editmode? */ - if(te->idcode==ID_SCE) { - if(scene!=(Scene *)tselem->id) { - ED_screen_set_scene(C, (Scene *)tselem->id); - } - } - else if(te->idcode==ID_GR) { - Group *gr= (Group *)tselem->id; - GroupObject *gob; - - if(extend) { - int sel= BA_SELECT; - for(gob= gr->gobject.first; gob; gob= gob->next) { - if(gob->ob->flag & SELECT) { - sel= BA_DESELECT; - break; - } - } - - for(gob= gr->gobject.first; gob; gob= gob->next) { - ED_base_object_select(object_in_scene(gob->ob, scene), sel); - } - } - else { - scene_deselect_all(scene); - - for(gob= gr->gobject.first; gob; gob= gob->next) { - if((gob->ob->flag & SELECT) == 0) - ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); - } - } - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { - WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); - } else { // rest of types - tree_element_active(C, scene, soops, te, 1); - } - - } - else tree_element_type_active(C, scene, soops, te, tselem, 1+(extend!=0)); - - return 1; - } - } - - for(te= te->subtree.first; te; te= te->next) { - if(do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1; - } - return 0; -} - -/* event can enterkey, then it opens/closes */ -static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event) -{ - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - TreeElement *te; - float fmval[2]; - int extend= RNA_boolean_get(op->ptr, "extend"); - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); - - if(!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX) - return OPERATOR_CANCELLED; - - for(te= soops->tree.first; te; te= te->next) { - if(do_outliner_item_activate(C, scene, ar, soops, te, extend, fmval)) break; - } - - if(te) { - ED_undo_push(C, "Outliner click event"); - } - else { - short selecting= -1; - int row; - - /* get row number - 100 here is just a dummy value since we don't need the column */ - UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET, - fmval[0], fmval[1], NULL, &row); - - /* select relevant row */ - outliner_select(soops, &soops->tree, &row, &selecting); - - soops->storeflag |= SO_TREESTORE_REDRAW; - - ED_undo_push(C, "Outliner selection event"); - } - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_item_activate(wmOperatorType *ot) -{ - ot->name= "Activate Item"; - ot->idname= "OUTLINER_OT_item_activate"; - ot->description= "Handle mouse clicks to activate/select items"; - - ot->invoke= outliner_item_activate; - - ot->poll= ED_operator_outliner_active; - - RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection for activation."); -} - -/* *********** */ - -static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, int all, const float mval[2]) -{ - - if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { - TreeStoreElem *tselem= TREESTORE(te); - - /* all below close/open? */ - if(all) { - tselem->flag &= ~TSE_CLOSED; - outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); - } - else { - if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; - else tselem->flag |= TSE_CLOSED; - } - - return 1; - } - - for(te= te->subtree.first; te; te= te->next) { - if(do_outliner_item_openclose(C, soops, te, all, mval)) - return 1; - } - return 0; - -} - -/* event can enterkey, then it opens/closes */ -static int outliner_item_openclose(bContext *C, wmOperator *op, wmEvent *event) -{ - ARegion *ar= CTX_wm_region(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - TreeElement *te; - float fmval[2]; - int all= RNA_boolean_get(op->ptr, "all"); - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); - - for(te= soops->tree.first; te; te= te->next) { - if(do_outliner_item_openclose(C, soops, te, all, fmval)) - break; - } - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_item_openclose(wmOperatorType *ot) -{ - ot->name= "Open/Close Item"; - ot->idname= "OUTLINER_OT_item_openclose"; - ot->description= "Toggle whether item under cursor is enabled or closed"; - - ot->invoke= outliner_item_openclose; - - ot->poll= ED_operator_outliner_active; - - RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items."); - -} - - -/* ********************************************** */ - -static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, TreeElement *te, const float mval[2]) -{ - - if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { - TreeStoreElem *tselem= TREESTORE(te); - - /* name and first icon */ - if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { - - /* can't rename rna datablocks entries */ - if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) - ; - else if(ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) - error("Cannot edit builtin name"); - else if(ELEM3(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) - error("Cannot edit sequence name"); - else if(tselem->id->lib) { - // XXX error_libdata(); - } - else if(te->idcode == ID_LI && te->parent) { - error("Cannot edit the path of an indirectly linked library"); - } - else { - tselem->flag |= TSE_TEXTBUT; - ED_region_tag_redraw(ar); - } - } - return 1; - } - - for(te= te->subtree.first; te; te= te->next) { - if(do_outliner_item_rename(C, ar, soops, te, mval)) return 1; - } - return 0; -} - -static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), wmEvent *event) -{ - ARegion *ar= CTX_wm_region(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - TreeElement *te; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); - - for(te= soops->tree.first; te; te= te->next) { - if(do_outliner_item_rename(C, ar, soops, te, fmval)) break; - } - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_item_rename(wmOperatorType *ot) -{ - ot->name= "Rename Item"; - ot->idname= "OUTLINER_OT_item_rename"; - ot->description= "Rename item under cursor"; - - ot->invoke= outliner_item_rename; - - ot->poll= ED_operator_outliner_active; -} - -static TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) -{ - TreeElement *te, *tes; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->type==0) { - if(tselem->id==id) return te; - /* only deeper on scene or object */ - if( te->idcode==ID_OB || te->idcode==ID_SCE || (soops->outlinevis == SO_GROUPS && te->idcode==ID_GR)) { - tes= outliner_find_id(soops, &te->subtree, id); - if(tes) return tes; - } - } - } - return NULL; -} - -static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *so= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - View2D *v2d= &ar->v2d; - - TreeElement *te; - int xdelta, ytop; - - // TODO: make this get this info from context instead... - if (OBACT == NULL) - return OPERATOR_CANCELLED; - - te= outliner_find_id(so, &so->tree, (ID *)OBACT); - if (te) { - /* make te->ys center of view */ - ytop= (int)(te->ys + (v2d->mask.ymax - v2d->mask.ymin)/2); - if (ytop>0) ytop= 0; - - v2d->cur.ymax= (float)ytop; - v2d->cur.ymin= (float)(ytop-(v2d->mask.ymax - v2d->mask.ymin)); - - /* make te->xs ==> te->xend center of view */ - xdelta = (int)(te->xs - v2d->cur.xmin); - v2d->cur.xmin += xdelta; - v2d->cur.xmax += xdelta; - - so->storeflag |= SO_TREESTORE_REDRAW; - } - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_show_active(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Show Active"; - ot->idname= "OUTLINER_OT_show_active"; - ot->description= "Adjust the view so that the active Object is shown centered"; - - /* callbacks */ - ot->exec= outliner_show_active_exec; - ot->poll= ED_operator_outliner_active; -} - -/* tse is not in the treestore, we use its contents to find a match */ -static TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) -{ - TreeStore *ts= soops->treestore; - TreeStoreElem *tselem; - int a; - - if(tse->id==NULL) return NULL; - - /* check if 'tse' is in treestore */ - tselem= ts->data; - for(a=0; a<ts->usedelem; a++, tselem++) { - if((tse->type==0 && tselem->type==0) || (tselem->type==tse->type && tselem->nr==tse->nr)) { - if(tselem->id==tse->id) { - break; - } - } - } - if(tselem) - return outliner_find_tree_element(&soops->tree, a); - - return NULL; -} - - -/* Called to find an item based on name. - */ -#if 0 - -/* recursive helper for function below */ -static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) -{ - TreeStoreElem *tselem= TREESTORE(te); - - /* store coord and continue, we need coordinates for elements outside view too */ - te->xs= (float)startx; - te->ys= (float)(*starty); - *starty-= UI_UNIT_Y; - - if((tselem->flag & TSE_CLOSED)==0) { - TreeElement *ten; - for(ten= te->subtree.first; ten; ten= ten->next) { - outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty); - } - } - -} - -/* to retrieve coordinates with redrawing the entire tree */ -static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops) -{ - TreeElement *te; - int starty= (int)(ar->v2d.tot.ymax)-UI_UNIT_Y; - int startx= 0; - - for(te= soops->tree.first; te; te= te->next) { - outliner_set_coordinates_element(soops, te, startx, &starty); - } -} - -/* find next element that has this name */ -static TreeElement *outliner_find_named(SpaceOops *soops, ListBase *lb, char *name, int flags, TreeElement *prev, int *prevFound) -{ - TreeElement *te, *tes; - - for (te= lb->first; te; te= te->next) { - int found = outliner_filter_has_name(te, name, flags); - - if(found) { - /* name is right, but is element the previous one? */ - if (prev) { - if ((te != prev) && (*prevFound)) - return te; - if (te == prev) { - *prevFound = 1; - } - } - else - return te; - } - - tes= outliner_find_named(soops, &te->subtree, name, flags, prev, prevFound); - if(tes) return tes; - } - - /* nothing valid found */ - return NULL; -} - -static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *soops, int again, int flags) -{ - TreeElement *te= NULL; - TreeElement *last_find; - TreeStoreElem *tselem; - int ytop, xdelta, prevFound=0; - char name[32]; - - /* get last found tree-element based on stored search_tse */ - last_find= outliner_find_tse(soops, &soops->search_tse); - - /* determine which type of search to do */ - if (again && last_find) { - /* no popup panel - previous + user wanted to search for next after previous */ - BLI_strncpy(name, soops->search_string, sizeof(name)); - flags= soops->search_flags; - - /* try to find matching element */ - te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound); - if (te==NULL) { - /* no more matches after previous, start from beginning again */ - prevFound= 1; - te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound); - } - } - else { - /* pop up panel - no previous, or user didn't want search after previous */ - strcpy(name, ""); -// XXX if (sbutton(name, 0, sizeof(name)-1, "Find: ") && name[0]) { -// te= outliner_find_named(soops, &soops->tree, name, flags, NULL, &prevFound); -// } -// else return; /* XXX RETURN! XXX */ - } - - /* do selection and reveal */ - if (te) { - tselem= TREESTORE(te); - if (tselem) { - /* expand branches so that it will be visible, we need to get correct coordinates */ - if( outliner_open_back(soops, te)) - outliner_set_coordinates(ar, soops); - - /* deselect all visible, and select found element */ - outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); - tselem->flag |= TSE_SELECTED; - - /* make te->ys center of view */ - ytop= (int)(te->ys + (ar->v2d.mask.ymax-ar->v2d.mask.ymin)/2); - if(ytop>0) ytop= 0; - ar->v2d.cur.ymax= (float)ytop; - ar->v2d.cur.ymin= (float)(ytop-(ar->v2d.mask.ymax-ar->v2d.mask.ymin)); - - /* make te->xs ==> te->xend center of view */ - xdelta = (int)(te->xs - ar->v2d.cur.xmin); - ar->v2d.cur.xmin += xdelta; - ar->v2d.cur.xmax += xdelta; - - /* store selection */ - soops->search_tse= *tselem; - - BLI_strncpy(soops->search_string, name, 33); - soops->search_flags= flags; - - /* redraw */ - soops->storeflag |= SO_TREESTORE_REDRAW; - } - } - else { - /* no tree-element found */ - error("Not found: %s", name); - } -} -#endif - -/* helper function for tree_element_shwo_hierarchy() - recursively checks whether subtrees have any objects*/ -static int subtree_has_objects(SpaceOops *soops, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->type==0 && te->idcode==ID_OB) return 1; - if( subtree_has_objects(soops, &te->subtree)) return 1; - } - return 0; -} - -/* recursive helper function for Show Hierarchy operator */ -static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - - /* open all object elems, close others */ - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - - if(tselem->type==0) { - if(te->idcode==ID_SCE) { - if(tselem->id!=(ID *)scene) tselem->flag |= TSE_CLOSED; - else tselem->flag &= ~TSE_CLOSED; - } - else if(te->idcode==ID_OB) { - if(subtree_has_objects(soops, &te->subtree)) tselem->flag &= ~TSE_CLOSED; - else tselem->flag |= TSE_CLOSED; - } - } - else tselem->flag |= TSE_CLOSED; - - if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree); - } -} - -/* show entire object level hierarchy */ -static int outliner_show_hierarchy_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - ARegion *ar= CTX_wm_region(C); - Scene *scene= CTX_data_scene(C); - - /* recursively open/close levels */ - tree_element_show_hierarchy(scene, soops, &soops->tree); - - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_show_hierarchy(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Show Hierarchy"; - ot->idname= "OUTLINER_OT_show_hierarchy"; - ot->description= "Open all object entries and close all others"; - - /* callbacks */ - ot->exec= outliner_show_hierarchy_exec; - ot->poll= ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views... - - /* no undo or registry, UI option */ -} - -void outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for (te= lb->first; te && *index >= 0; te=te->next, (*index)--) { - tselem= TREESTORE(te); - - /* if we've encountered the right item, set its 'Outliner' selection status */ - if (*index == 0) { - /* this should be the last one, so no need to do anything with index */ - if ((te->flag & TE_ICONROW)==0) { - /* -1 value means toggle testing for now... */ - if (*selecting == -1) { - if (tselem->flag & TSE_SELECTED) - *selecting= 0; - else - *selecting= 1; - } - - /* set selection */ - if (*selecting) - tselem->flag |= TSE_SELECTED; - else - tselem->flag &= ~TSE_SELECTED; - } - } - else if ((tselem->flag & TSE_CLOSED)==0) { - /* Only try selecting sub-elements if we haven't hit the right element yet - * - * Hack warning: - * Index must be reduced before supplying it to the sub-tree to try to do - * selection, however, we need to increment it again for the next loop to - * function correctly - */ - (*index)--; - outliner_select(soops, &te->subtree, index, selecting); - (*index)++; - } - } -} - -/* ************ SELECTION OPERATIONS ********* */ - -static void set_operation_types(SpaceOops *soops, ListBase *lb, - int *scenelevel, - int *objectlevel, - int *idlevel, - int *datalevel) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->flag & TSE_SELECTED) { - if(tselem->type) { - if(*datalevel==0) - *datalevel= tselem->type; - else if(*datalevel!=tselem->type) - *datalevel= -1; - } - else { - int idcode= GS(tselem->id->name); - switch(idcode) { - case ID_SCE: - *scenelevel= 1; - break; - case ID_OB: - *objectlevel= 1; - break; - - case ID_ME: case ID_CU: case ID_MB: case ID_LT: - case ID_LA: case ID_AR: case ID_CA: - case ID_MA: case ID_TE: case ID_IP: case ID_IM: - case ID_SO: case ID_KE: case ID_WO: case ID_AC: - case ID_NLA: case ID_TXT: case ID_GR: - if(*idlevel==0) *idlevel= idcode; - else if(*idlevel!=idcode) *idlevel= -1; - break; - } - } - } - if((tselem->flag & TSE_CLOSED)==0) { - set_operation_types(soops, &te->subtree, - scenelevel, objectlevel, idlevel, datalevel); - } - } -} - -static void unlink_material_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem)) -{ - Material **matar=NULL; - int a, totcol=0; - - if( GS(tsep->id->name)==ID_OB) { - Object *ob= (Object *)tsep->id; - totcol= ob->totcol; - matar= ob->mat; - } - else if( GS(tsep->id->name)==ID_ME) { - Mesh *me= (Mesh *)tsep->id; - totcol= me->totcol; - matar= me->mat; - } - else if( GS(tsep->id->name)==ID_CU) { - Curve *cu= (Curve *)tsep->id; - totcol= cu->totcol; - matar= cu->mat; - } - else if( GS(tsep->id->name)==ID_MB) { - MetaBall *mb= (MetaBall *)tsep->id; - totcol= mb->totcol; - matar= mb->mat; - } - - for(a=0; a<totcol; a++) { - if(a==te->index && matar[a]) { - matar[a]->id.us--; - matar[a]= NULL; - } - } -} - -static void unlink_texture_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem)) -{ - MTex **mtex= NULL; - int a; - - if( GS(tsep->id->name)==ID_MA) { - Material *ma= (Material *)tsep->id; - mtex= ma->mtex; - } - else if( GS(tsep->id->name)==ID_LA) { - Lamp *la= (Lamp *)tsep->id; - mtex= la->mtex; - } - else if( GS(tsep->id->name)==ID_WO) { - World *wrld= (World *)tsep->id; - mtex= wrld->mtex; - } - else return; - - for(a=0; a<MAX_MTEX; a++) { - if(a==te->index && mtex[a]) { - if(mtex[a]->tex) { - mtex[a]->tex->id.us--; - mtex[a]->tex= NULL; - } - } - } -} - -static void unlink_group_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) -{ - Group *group= (Group *)tselem->id; - - if(tsep) { - if( GS(tsep->id->name)==ID_OB) { - Object *ob= (Object *)tsep->id; - ob->dup_group= NULL; - } - } - else { - unlink_group(group); - } -} - -static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, - void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te=lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->flag & TSE_SELECTED) { - if(tselem->type==0) { - TreeStoreElem *tsep= TREESTORE(te->parent); - operation_cb(C, scene, te, tsep, tselem); - } - } - if((tselem->flag & TSE_CLOSED)==0) { - outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb); - } - } -} - -/* */ - -static void object_select_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - - if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); - if(base && ((base->object->restrictflag & OB_RESTRICT_VIEW)==0)) { - base->flag |= SELECT; - base->object->flag |= SELECT; - } -} - -static void object_deselect_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - - if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); - if(base) { - base->flag &= ~SELECT; - base->object->flag &= ~SELECT; - } -} - -static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Base *base= (Base *)te->directdata; - - if(base==NULL) - base= object_in_scene((Object *)tselem->id, scene); - if(base) { - // check also library later - if(scene->obedit==base->object) - ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); - - ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); - te->directdata= NULL; - tselem->id= NULL; - } - -} - -static void id_local_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - if(tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) { - tselem->id->lib= NULL; - tselem->id->flag= LIB_LOCAL; - new_id(NULL, tselem->id, NULL); - } -} - -static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) -{ - Group *group= (Group *)tselem->id; - GroupObject *gob; - Base *base; - - for(gob=group->gobject.first; gob; gob=gob->next) { - base= object_in_scene(gob->ob, scene); - if (base) { - base->object->flag |= SELECT; - base->flag |= SELECT; - } else { - /* link to scene */ - base= MEM_callocN( sizeof(Base), "add_base"); - BLI_addhead(&scene->base, base); - base->lay= (1<<20)-1; /*v3d->lay;*/ /* would be nice to use the 3d layer but the include's not here */ - gob->ob->flag |= SELECT; - base->flag = gob->ob->flag; - base->object= gob->ob; - id_lib_extern((ID *)gob->ob); /* incase these are from a linked group */ - } - } -} - -static void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, - void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te=lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->flag & TSE_SELECTED) { - if(tselem->type==0 && te->idcode==ID_OB) { - // when objects selected in other scenes... dunno if that should be allowed - Scene *scene_owner= (Scene *)outliner_search_back(soops, te, ID_SCE); - if(scene_owner && scene_act != scene_owner) { - ED_screen_set_scene(C, scene_owner); - } - /* important to use 'scene_owner' not scene_act else deleting objects can crash. - * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the - * outliner isnt showing scenes: Visible Layer draw mode for eg. */ - operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem); - } - } - if((tselem->flag & TSE_CLOSED)==0) { - outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb); - } - } -} - -/* ******************************************** */ - -static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) -{ - bPoseChannel *pchan= (bPoseChannel *)te->directdata; - - if(event==1) - pchan->bone->flag |= BONE_SELECTED; - else if(event==2) - pchan->bone->flag &= ~BONE_SELECTED; - else if(event==3) { - pchan->bone->flag |= BONE_HIDDEN_P; - pchan->bone->flag &= ~BONE_SELECTED; - } - else if(event==4) - pchan->bone->flag &= ~BONE_HIDDEN_P; -} - -static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) -{ - Bone *bone= (Bone *)te->directdata; - - if(event==1) - bone->flag |= BONE_SELECTED; - else if(event==2) - bone->flag &= ~BONE_SELECTED; - else if(event==3) { - bone->flag |= BONE_HIDDEN_P; - bone->flag &= ~BONE_SELECTED; - } - else if(event==4) - bone->flag &= ~BONE_HIDDEN_P; -} - -static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) -{ - EditBone *ebone= (EditBone *)te->directdata; - - if(event==1) - ebone->flag |= BONE_SELECTED; - else if(event==2) - ebone->flag &= ~BONE_SELECTED; - else if(event==3) { - ebone->flag |= BONE_HIDDEN_A; - ebone->flag &= ~BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; - } - else if(event==4) - ebone->flag &= ~BONE_HIDDEN_A; -} - -static void sequence_cb(int event, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tselem)) -{ -// Sequence *seq= (Sequence*) te->directdata; - if(event==1) { -// XXX select_single_seq(seq, 1); - } -} - -static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb, - void (*operation_cb)(int, TreeElement *, TreeStoreElem *)) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te=lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(tselem->flag & TSE_SELECTED) { - if(tselem->type==type) { - operation_cb(event, te, tselem); - } - } - if((tselem->flag & TSE_CLOSED)==0) { - outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb); - } - } -} - -static void outliner_del(bContext *C, Scene *scene, ARegion *UNUSED(ar), SpaceOops *soops) -{ - - if(soops->outlinevis==SO_SEQUENCE) - ;// del_seq(); - else { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb); - DAG_scene_sort(CTX_data_main(C), scene); - ED_undo_push(C, "Delete Objects"); - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); - } -} - -/* **************************************** */ - -static EnumPropertyItem prop_object_op_types[] = { - {1, "SELECT", 0, "Select", ""}, - {2, "DESELECT", 0, "Deselect", ""}, - {4, "DELETE", 0, "Delete", ""}, - {6, "TOGVIS", 0, "Toggle Visible", ""}, - {7, "TOGSEL", 0, "Toggle Selectable", ""}, - {8, "TOGREN", 0, "Toggle Renderable", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int outliner_object_operation_exec(bContext *C, wmOperator *op) -{ - Main *bmain= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - int event; - const char *str= NULL; - - /* check for invalid states */ - if (soops == NULL) - return OPERATOR_CANCELLED; - - event= RNA_enum_get(op->ptr, "type"); - - if(event==1) { - Scene *sce= scene; // to be able to delete, scenes are set... - outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb); - if(scene != sce) { - ED_screen_set_scene(C, sce); - } - - str= "Select Objects"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - else if(event==2) { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb); - str= "Deselect Objects"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - else if(event==4) { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb); - DAG_scene_sort(bmain, scene); - str= "Delete Objects"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); - } - else if(event==5) { /* disabled, see above enum (ton) */ - outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb); - str= "Localized Objects"; - } - else if(event==6) { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); - str= "Toggle Visibility"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_VISIBLE, scene); - } - else if(event==7) { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); - str= "Toggle Selectability"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - } - else if(event==8) { - outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); - str= "Toggle Renderability"; - WM_event_add_notifier(C, NC_SCENE|ND_OB_RENDER, scene); - } - - ED_undo_push(C, str); - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_object_operation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Outliner Object Operation"; - ot->idname= "OUTLINER_OT_object_operation"; - ot->description= ""; - - /* callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= outliner_object_operation_exec; - ot->poll= ED_operator_outliner_active; - - ot->flag= 0; - - ot->prop= RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", ""); -} - -/* **************************************** */ - -static EnumPropertyItem prop_group_op_types[] = { - {1, "UNLINK", 0, "Unlink", ""}, - {2, "LOCAL", 0, "Make Local", ""}, - {3, "LINK", 0, "Link Group Objects to Scene", ""}, - {4, "TOGVIS", 0, "Toggle Visible", ""}, - {5, "TOGSEL", 0, "Toggle Selectable", ""}, - {6, "TOGREN", 0, "Toggle Renderable", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int outliner_group_operation_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - int event; - - /* check for invalid states */ - if (soops == NULL) - return OPERATOR_CANCELLED; - - event= RNA_enum_get(op->ptr, "type"); - - if(event==1) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); - ED_undo_push(C, "Unlink group"); - } - else if(event==2) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); - ED_undo_push(C, "Localized Data"); - } - else if(event==3) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); - ED_undo_push(C, "Link Group Objects to Scene"); - } - - - WM_event_add_notifier(C, NC_GROUP, NULL); - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_group_operation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Outliner Group Operation"; - ot->idname= "OUTLINER_OT_group_operation"; - ot->description= ""; - - /* callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= outliner_group_operation_exec; - ot->poll= ED_operator_outliner_active; - - ot->flag= 0; - - ot->prop= RNA_def_enum(ot->srna, "type", prop_group_op_types, 0, "Group Operation", ""); -} - -/* **************************************** */ - -static EnumPropertyItem prop_id_op_types[] = { - {1, "UNLINK", 0, "Unlink", ""}, - {2, "LOCAL", 0, "Make Local", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int outliner_id_operation_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; - int event; - - /* check for invalid states */ - if (soops == NULL) - return OPERATOR_CANCELLED; - - set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - - event= RNA_enum_get(op->ptr, "type"); - - if(event==1) { - switch(idlevel) { - case ID_MA: - outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_material_cb); - ED_undo_push(C, "Unlink material"); - break; - case ID_TE: - outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_texture_cb); - ED_undo_push(C, "Unlink texture"); - break; - default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); - } - } - else if(event==2) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); - ED_undo_push(C, "Localized Data"); - } - - /* wrong notifier still... */ - WM_event_add_notifier(C, NC_OBJECT, NULL); - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_id_operation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Outliner ID data Operation"; - ot->idname= "OUTLINER_OT_id_operation"; - ot->description= ""; - - /* callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= outliner_id_operation_exec; - ot->poll= ED_operator_outliner_active; - - ot->flag= 0; - - ot->prop= RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID data Operation", ""); -} - -/* **************************************** */ - -static EnumPropertyItem prop_data_op_types[] = { - {1, "SELECT", 0, "Select", ""}, - {2, "DESELECT", 0, "Deselect", ""}, - {3, "HIDE", 0, "Hide", ""}, - {4, "UNHIDE", 0, "Unhide", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int outliner_data_operation_exec(bContext *C, wmOperator *op) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; - int event; - - /* check for invalid states */ - if (soops == NULL) - return OPERATOR_CANCELLED; - - event= RNA_enum_get(op->ptr, "type"); - set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - - if(datalevel==TSE_POSE_CHANNEL) { - if(event>0) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); - ED_undo_push(C, "PoseChannel operation"); - } - } - else if(datalevel==TSE_BONE) { - if(event>0) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); - ED_undo_push(C, "Bone operation"); - } - } - else if(datalevel==TSE_EBONE) { - if(event>0) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); - ED_undo_push(C, "EditBone operation"); - } - } - else if(datalevel==TSE_SEQUENCE) { - if(event>0) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb); - } - } - - return OPERATOR_FINISHED; -} - - -void OUTLINER_OT_data_operation(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Outliner Data Operation"; - ot->idname= "OUTLINER_OT_data_operation"; - ot->description= ""; - - /* callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= outliner_data_operation_exec; - ot->poll= ED_operator_outliner_active; - - ot->flag= 0; - - ot->prop= RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", ""); -} - - -/* ******************** */ - - -static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, wmEvent *event, const float mval[2]) -{ - - if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { - int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; - TreeStoreElem *tselem= TREESTORE(te); - - /* select object that's clicked on and popup context menu */ - if (!(tselem->flag & TSE_SELECTED)) { - - if ( outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1) ) - outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); - - tselem->flag |= TSE_SELECTED; - /* redraw, same as outliner_select function */ - soops->storeflag |= SO_TREESTORE_REDRAW; - ED_region_tag_redraw(ar); - } - - set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - - if(scenelevel) { - //if(objectlevel || datalevel || idlevel) error("Mixed selection"); - //else pupmenu("Scene Operations%t|Delete"); - } - else if(objectlevel) { - WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL); - } - else if(idlevel) { - if(idlevel==-1 || datalevel) error("Mixed selection"); - else { - if (idlevel==ID_GR) - WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL); - else - WM_operator_name_call(C, "OUTLINER_OT_id_operation", WM_OP_INVOKE_REGION_WIN, NULL); - } - } - else if(datalevel) { - if(datalevel==-1) error("Mixed selection"); - else { - WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); - } - } - - return 1; - } - - for(te= te->subtree.first; te; te= te->next) { - if(do_outliner_operation_event(C, scene, ar, soops, te, event, mval)) - return 1; - } - return 0; -} - - -static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *event) -{ - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - SpaceOops *soops= CTX_wm_space_outliner(C); - TreeElement *te; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); - - for(te= soops->tree.first; te; te= te->next) { - if(do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break; - } - - return OPERATOR_FINISHED; -} - -/* Menu only! Calls other operators */ -void OUTLINER_OT_operation(wmOperatorType *ot) -{ - ot->name= "Execute Operation"; - ot->idname= "OUTLINER_OT_operation"; - ot->description= "Context menu for item operations"; - - ot->invoke= outliner_operation; - - ot->poll= ED_operator_outliner_active; -} - - - -/* ***************** ANIMATO OPERATIONS ********************************** */ -/* KeyingSet and Driver Creation - Helper functions */ - -/* specialised poll callback for these operators to work in Datablocks view only */ -static int ed_operator_outliner_datablocks_active(bContext *C) -{ - ScrArea *sa= CTX_wm_area(C); - if ((sa) && (sa->spacetype==SPACE_OUTLINER)) { - SpaceOops *so= CTX_wm_space_outliner(C); - return (so->outlinevis == SO_DATABLOCKS); - } - return 0; -} - - -/* Helper func to extract an RNA path from selected tree element - * NOTE: the caller must zero-out all values of the pointers that it passes here first, as - * this function does not do that yet - */ -static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, - ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode)) -{ - ListBase hierarchy = {NULL, NULL}; - LinkData *ld; - TreeElement *tem, *temnext, *temsub; - TreeStoreElem *tse, *tsenext; - PointerRNA *ptr, *nextptr; - PropertyRNA *prop; - char *newpath=NULL; - - /* optimise tricks: - * - Don't do anything if the selected item is a 'struct', but arrays are allowed - */ - if (tselem->type == TSE_RNA_STRUCT) - return; - - /* Overview of Algorithm: - * 1. Go up the chain of parents until we find the 'root', taking note of the - * levels encountered in reverse-order (i.e. items are added to the start of the list - * for more convenient looping later) - * 2. Walk down the chain, adding from the first ID encountered - * (which will become the 'ID' for the KeyingSet Path), and build a - * path as we step through the chain - */ - - /* step 1: flatten out hierarchy of parents into a flat chain */ - for (tem= te->parent; tem; tem= tem->parent) { - ld= MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()"); - ld->data= tem; - BLI_addhead(&hierarchy, ld); - } - - /* step 2: step down hierarchy building the path (NOTE: addhead in previous loop was needed so that we can loop like this) */ - for (ld= hierarchy.first; ld; ld= ld->next) { - /* get data */ - tem= (TreeElement *)ld->data; - tse= TREESTORE(tem); - ptr= &tem->rnaptr; - prop= tem->directdata; - - /* check if we're looking for first ID, or appending to path */ - if (*id) { - /* just 'append' property to path - * - to prevent memory leaks, we must write to newpath not path, then free old path + swap them - */ - if(tse->type == TSE_RNA_PROPERTY) { - if(RNA_property_type(prop) == PROP_POINTER) { - /* for pointer we just append property name */ - newpath= RNA_path_append(*path, ptr, prop, 0, NULL); - } - else if(RNA_property_type(prop) == PROP_COLLECTION) { - char buf[128], *name; - - temnext= (TreeElement*)(ld->next->data); - tsenext= TREESTORE(temnext); - - nextptr= &temnext->rnaptr; - name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf)); - - if(name) { - /* if possible, use name as a key in the path */ - newpath= RNA_path_append(*path, NULL, prop, 0, name); - - if(name != buf) - MEM_freeN(name); - } - else { - /* otherwise use index */ - int index= 0; - - for(temsub=tem->subtree.first; temsub; temsub=temsub->next, index++) - if(temsub == temnext) - break; - - newpath= RNA_path_append(*path, NULL, prop, index, NULL); - } - - ld= ld->next; - } - } - - if(newpath) { - if (*path) MEM_freeN(*path); - *path= newpath; - newpath= NULL; - } - } - else { - /* no ID, so check if entry is RNA-struct, and if that RNA-struct is an ID datablock to extract info from */ - if (tse->type == TSE_RNA_STRUCT) { - /* ptr->data not ptr->id.data seems to be the one we want, since ptr->data is sometimes the owner of this ID? */ - if(RNA_struct_is_ID(ptr->type)) { - *id= (ID *)ptr->data; - - /* clear path */ - if(*path) { - MEM_freeN(*path); - path= NULL; - } - } - } - } - } - - /* step 3: if we've got an ID, add the current item to the path */ - if (*id) { - /* add the active property to the path */ - ptr= &te->rnaptr; - prop= te->directdata; - - /* array checks */ - if (tselem->type == TSE_RNA_ARRAY_ELEM) { - /* item is part of an array, so must set the array_index */ - *array_index= te->index; - } - else if (RNA_property_array_length(ptr, prop)) { - /* entire array was selected, so keyframe all */ - *flag |= KSP_FLAG_WHOLE_ARRAY; - } - - /* path */ - newpath= RNA_path_append(*path, NULL, prop, 0, NULL); - if (*path) MEM_freeN(*path); - *path= newpath; - } - - /* free temp data */ - BLI_freelistN(&hierarchy); -} - -/* ***************** KEYINGSET OPERATIONS *************** */ - -/* These operators are only available in databrowser mode for now, as - * they depend on having RNA paths and/or hierarchies available. - */ -enum { - DRIVERS_EDITMODE_ADD = 0, - DRIVERS_EDITMODE_REMOVE, -} /*eDrivers_EditModes*/; - -/* Utilities ---------------------------------- */ - -/* Recursively iterate over tree, finding and working on selected items */ -static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportList *reports, short mode) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for (te= tree->first; te; te=te->next) { - tselem= TREESTORE(te); - - /* if item is selected, perform operation */ - if (tselem->flag & TSE_SELECTED) { - ID *id= NULL; - char *path= NULL; - int array_index= 0; - short flag= 0; - short groupmode= KSP_GROUP_KSNAME; - - /* check if RNA-property described by this selected element is an animateable prop */ - if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) { - /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, - &id, &path, &array_index, &flag, &groupmode); - } - - /* only if ID and path were set, should we perform any actions */ - if (id && path) { - short dflags = CREATEDRIVER_WITH_DEFAULT_DVAR; - int arraylen = 1; - - /* array checks */ - if (flag & KSP_FLAG_WHOLE_ARRAY) { - /* entire array was selected, so add drivers for all */ - arraylen= RNA_property_array_length(&te->rnaptr, te->directdata); - } - else - arraylen= array_index; - - /* we should do at least one step */ - if (arraylen == array_index) - arraylen++; - - /* for each array element we should affect, add driver */ - for (; array_index < arraylen; array_index++) { - /* action depends on mode */ - switch (mode) { - case DRIVERS_EDITMODE_ADD: - { - /* add a new driver with the information obtained (only if valid) */ - ANIM_add_driver(reports, id, path, array_index, dflags, DRIVER_TYPE_PYTHON); - } - break; - case DRIVERS_EDITMODE_REMOVE: - { - /* remove driver matching the information obtained (only if valid) */ - ANIM_remove_driver(reports, id, path, array_index, dflags); - } - break; - } - } - - /* free path, since it had to be generated */ - MEM_freeN(path); - } - - - } - - /* go over sub-tree */ - if ((tselem->flag & TSE_CLOSED)==0) - do_outliner_drivers_editop(soops, &te->subtree, reports, mode); - } -} - -/* Add Operator ---------------------------------- */ - -static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op) -{ - SpaceOops *soutliner= CTX_wm_space_outliner(C); - - /* check for invalid states */ - if (soutliner == NULL) - return OPERATOR_CANCELLED; - - /* recursively go into tree, adding selected items */ - do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_ADD); - - /* send notifiers */ - WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot) -{ - /* api callbacks */ - ot->idname= "OUTLINER_OT_drivers_add_selected"; - ot->name= "Add Drivers for Selected"; - ot->description= "Add drivers to selected items"; - - /* api callbacks */ - ot->exec= outliner_drivers_addsel_exec; - ot->poll= ed_operator_outliner_datablocks_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} - - -/* Remove Operator ---------------------------------- */ - -static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op) -{ - SpaceOops *soutliner= CTX_wm_space_outliner(C); - - /* check for invalid states */ - if (soutliner == NULL) - return OPERATOR_CANCELLED; - - /* recursively go into tree, adding selected items */ - do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE); - - /* send notifiers */ - WM_event_add_notifier(C, ND_KEYS, NULL); // XXX - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot) -{ - /* identifiers */ - ot->idname= "OUTLINER_OT_drivers_delete_selected"; - ot->name= "Delete Drivers for Selected"; - ot->description= "Delete drivers assigned to selected items"; - - /* api callbacks */ - ot->exec= outliner_drivers_deletesel_exec; - ot->poll= ed_operator_outliner_datablocks_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* ***************** KEYINGSET OPERATIONS *************** */ - -/* These operators are only available in databrowser mode for now, as - * they depend on having RNA paths and/or hierarchies available. - */ -enum { - KEYINGSET_EDITMODE_ADD = 0, - KEYINGSET_EDITMODE_REMOVE, -} /*eKeyingSet_EditModes*/; - -/* Utilities ---------------------------------- */ - -/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */ -// TODO: should this be an API func? -static KeyingSet *verify_active_keyingset(Scene *scene, short add) -{ - KeyingSet *ks= NULL; - - /* sanity check */ - if (scene == NULL) - return NULL; - - /* try to find one from scene */ - if (scene->active_keyingset > 0) - ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); - - /* add if none found */ - // XXX the default settings have yet to evolve - if ((add) && (ks==NULL)) { - ks= BKE_keyingset_add(&scene->keyingsets, NULL, KEYINGSET_ABSOLUTE, 0); - scene->active_keyingset= BLI_countlist(&scene->keyingsets); - } - - return ks; -} - -/* Recursively iterate over tree, finding and working on selected items */ -static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for (te= tree->first; te; te=te->next) { - tselem= TREESTORE(te); - - /* if item is selected, perform operation */ - if (tselem->flag & TSE_SELECTED) { - ID *id= NULL; - char *path= NULL; - int array_index= 0; - short flag= 0; - short groupmode= KSP_GROUP_KSNAME; - - /* check if RNA-property described by this selected element is an animateable prop */ - if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) { - /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, - &id, &path, &array_index, &flag, &groupmode); - } - - /* only if ID and path were set, should we perform any actions */ - if (id && path) { - /* action depends on mode */ - switch (mode) { - case KEYINGSET_EDITMODE_ADD: - { - /* add a new path with the information obtained (only if valid) */ - // TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name - BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode); - ks->active_path= BLI_countlist(&ks->paths); - } - break; - case KEYINGSET_EDITMODE_REMOVE: - { - /* find the relevant path, then remove it from the KeyingSet */ - KS_Path *ksp= BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode); - - if (ksp) { - /* free path's data */ - BKE_keyingset_free_path(ks, ksp); - - ks->active_path= 0; - } - } - break; - } - - /* free path, since it had to be generated */ - MEM_freeN(path); - } - } - - /* go over sub-tree */ - if ((tselem->flag & TSE_CLOSED)==0) - do_outliner_keyingset_editop(soops, ks, &te->subtree, mode); - } -} - -/* Add Operator ---------------------------------- */ - -static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op) -{ - SpaceOops *soutliner= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - KeyingSet *ks= verify_active_keyingset(scene, 1); - - /* check for invalid states */ - if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set"); - return OPERATOR_CANCELLED; - } - if (soutliner == NULL) - return OPERATOR_CANCELLED; - - /* recursively go into tree, adding selected items */ - do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD); - - /* send notifiers */ - WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot) -{ - /* identifiers */ - ot->idname= "OUTLINER_OT_keyingset_add_selected"; - ot->name= "Keying Set Add Selected"; - ot->description= "Add selected items (blue-grey rows) to active Keying Set"; - - /* api callbacks */ - ot->exec= outliner_keyingset_additems_exec; - ot->poll= ed_operator_outliner_datablocks_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} - - -/* Remove Operator ---------------------------------- */ - -static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *UNUSED(op)) -{ - SpaceOops *soutliner= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - KeyingSet *ks= verify_active_keyingset(scene, 1); - - /* check for invalid states */ - if (soutliner == NULL) - return OPERATOR_CANCELLED; - - /* recursively go into tree, adding selected items */ - do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE); - - /* send notifiers */ - WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot) -{ - /* identifiers */ - ot->idname= "OUTLINER_OT_keyingset_remove_selected"; - ot->name= "Keying Set Remove Selected"; - ot->description = "Remove selected items (blue-grey rows) from active Keying Set"; - - /* api callbacks */ - ot->exec= outliner_keyingset_removeitems_exec; - ot->poll= ed_operator_outliner_datablocks_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} - -/* ***************** DRAW *************** */ - -/* make function calls a bit compacter */ -struct DrawIconArg { - uiBlock *block; - ID *id; - int xmax, x, y; - float alpha; -}; - -static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) -{ - /* restrict collumn clip... it has been coded by simply overdrawing, doesnt work for buttons */ - if(arg->x >= arg->xmax) - UI_icon_draw(arg->x, arg->y, icon); - else { - /* XXX investigate: button placement of icons is way different than UI_icon_draw? */ - float ufac= UI_UNIT_X/20.0f; - uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-3.0f*ufac, arg->y, UI_UNIT_X-4.0f*ufac, UI_UNIT_Y-4.0f*ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); - - if(arg->id) - uiButSetDragID(but, arg->id); - } - -} - -static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha) -{ - struct DrawIconArg arg; - - /* make function calls a bit compacter */ - arg.block= block; - arg.id= tselem->id; - arg.xmax= xmax; - arg.x= x; - arg.y= y; - arg.alpha= alpha; - - if(tselem->type) { - switch( tselem->type) { - case TSE_ANIM_DATA: - UI_icon_draw(x, y, ICON_ANIM_DATA); break; // xxx - case TSE_NLA: - UI_icon_draw(x, y, ICON_NLA); break; - case TSE_NLA_TRACK: - UI_icon_draw(x, y, ICON_NLA); break; // XXX - case TSE_NLA_ACTION: - UI_icon_draw(x, y, ICON_ACTION); break; - case TSE_DEFGROUP_BASE: - UI_icon_draw(x, y, ICON_GROUP_VERTEX); break; - case TSE_BONE: - case TSE_EBONE: - UI_icon_draw(x, y, ICON_BONE_DATA); break; - case TSE_CONSTRAINT_BASE: - UI_icon_draw(x, y, ICON_CONSTRAINT); break; - case TSE_MODIFIER_BASE: - UI_icon_draw(x, y, ICON_MODIFIER); break; - case TSE_LINKED_OB: - UI_icon_draw(x, y, ICON_OBJECT_DATA); break; - case TSE_LINKED_PSYS: - UI_icon_draw(x, y, ICON_PARTICLES); break; - case TSE_MODIFIER: - { - Object *ob= (Object *)tselem->id; - ModifierData *md= BLI_findlink(&ob->modifiers, tselem->nr); - switch(md->type) { - case eModifierType_Subsurf: - UI_icon_draw(x, y, ICON_MOD_SUBSURF); break; - case eModifierType_Armature: - UI_icon_draw(x, y, ICON_MOD_ARMATURE); break; - case eModifierType_Lattice: - UI_icon_draw(x, y, ICON_MOD_LATTICE); break; - case eModifierType_Curve: - UI_icon_draw(x, y, ICON_MOD_CURVE); break; - case eModifierType_Build: - UI_icon_draw(x, y, ICON_MOD_BUILD); break; - case eModifierType_Mirror: - UI_icon_draw(x, y, ICON_MOD_MIRROR); break; - case eModifierType_Decimate: - UI_icon_draw(x, y, ICON_MOD_DECIM); break; - case eModifierType_Wave: - UI_icon_draw(x, y, ICON_MOD_WAVE); break; - case eModifierType_Hook: - UI_icon_draw(x, y, ICON_HOOK); break; - case eModifierType_Softbody: - UI_icon_draw(x, y, ICON_MOD_SOFT); break; - case eModifierType_Boolean: - UI_icon_draw(x, y, ICON_MOD_BOOLEAN); break; - case eModifierType_ParticleSystem: - UI_icon_draw(x, y, ICON_MOD_PARTICLES); break; - case eModifierType_ParticleInstance: - UI_icon_draw(x, y, ICON_MOD_PARTICLES); break; - case eModifierType_EdgeSplit: - UI_icon_draw(x, y, ICON_MOD_EDGESPLIT); break; - case eModifierType_Array: - UI_icon_draw(x, y, ICON_MOD_ARRAY); break; - case eModifierType_UVProject: - UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break; - case eModifierType_Displace: - UI_icon_draw(x, y, ICON_MOD_DISPLACE); break; - case eModifierType_Shrinkwrap: - UI_icon_draw(x, y, ICON_MOD_SHRINKWRAP); break; - case eModifierType_Cast: - UI_icon_draw(x, y, ICON_MOD_CAST); break; - case eModifierType_MeshDeform: - UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; - case eModifierType_Bevel: - UI_icon_draw(x, y, ICON_MOD_BEVEL); break; - case eModifierType_Smooth: - UI_icon_draw(x, y, ICON_MOD_SMOOTH); break; - case eModifierType_SimpleDeform: - UI_icon_draw(x, y, ICON_MOD_SIMPLEDEFORM); break; - case eModifierType_Mask: - UI_icon_draw(x, y, ICON_MOD_MASK); break; - case eModifierType_Cloth: - UI_icon_draw(x, y, ICON_MOD_CLOTH); break; - case eModifierType_Explode: - UI_icon_draw(x, y, ICON_MOD_EXPLODE); break; - case eModifierType_Collision: - UI_icon_draw(x, y, ICON_MOD_PHYSICS); break; - case eModifierType_Fluidsim: - UI_icon_draw(x, y, ICON_MOD_FLUIDSIM); break; - case eModifierType_Multires: - UI_icon_draw(x, y, ICON_MOD_MULTIRES); break; - case eModifierType_Smoke: - UI_icon_draw(x, y, ICON_MOD_SMOKE); break; - case eModifierType_Solidify: - UI_icon_draw(x, y, ICON_MOD_SOLIDIFY); break; - case eModifierType_Screw: - UI_icon_draw(x, y, ICON_MOD_SCREW); break; - case eModifierType_DynamicPaint: - UI_icon_draw(x, y, ICON_MOD_DYNAMICPAINT); break; - default: - UI_icon_draw(x, y, ICON_DOT); break; - } - break; - } - case TSE_SCRIPT_BASE: - UI_icon_draw(x, y, ICON_TEXT); break; - case TSE_POSE_BASE: - UI_icon_draw(x, y, ICON_ARMATURE_DATA); break; - case TSE_POSE_CHANNEL: - UI_icon_draw(x, y, ICON_BONE_DATA); break; - case TSE_PROXY: - UI_icon_draw(x, y, ICON_GHOST); break; - case TSE_R_LAYER_BASE: - UI_icon_draw(x, y, ICON_RENDERLAYERS); break; - case TSE_R_LAYER: - UI_icon_draw(x, y, ICON_RENDERLAYERS); break; - case TSE_LINKED_LAMP: - UI_icon_draw(x, y, ICON_LAMP_DATA); break; - case TSE_LINKED_MAT: - UI_icon_draw(x, y, ICON_MATERIAL_DATA); break; - case TSE_POSEGRP_BASE: - UI_icon_draw(x, y, ICON_VERTEXSEL); break; - case TSE_SEQUENCE: - if(te->idcode==SEQ_MOVIE) - UI_icon_draw(x, y, ICON_SEQUENCE); - else if(te->idcode==SEQ_META) - UI_icon_draw(x, y, ICON_DOT); - else if(te->idcode==SEQ_SCENE) - UI_icon_draw(x, y, ICON_SCENE); - else if(te->idcode==SEQ_SOUND) - UI_icon_draw(x, y, ICON_SOUND); - else if(te->idcode==SEQ_IMAGE) - UI_icon_draw(x, y, ICON_IMAGE_COL); - else - UI_icon_draw(x, y, ICON_PARTICLES); - break; - case TSE_SEQ_STRIP: - UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT); - break; - case TSE_SEQUENCE_DUP: - UI_icon_draw(x, y, ICON_OBJECT_DATA); - break; - case TSE_RNA_STRUCT: - if(RNA_struct_is_ID(te->rnaptr.type)) { - arg.id= (ID *)te->rnaptr.data; - tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type)); - } - else - UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type)); - break; - default: - UI_icon_draw(x, y, ICON_DOT); break; - } - } - else if (GS(tselem->id->name) == ID_OB) { - Object *ob= (Object *)tselem->id; - switch (ob->type) { - case OB_LAMP: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LAMP); break; - case OB_MESH: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_MESH); break; - case OB_CAMERA: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CAMERA); break; - case OB_CURVE: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CURVE); break; - case OB_MBALL: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_META); break; - case OB_LATTICE: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LATTICE); break; - case OB_ARMATURE: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_ARMATURE); break; - case OB_FONT: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_FONT); break; - case OB_SURF: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SURFACE); break; - case OB_EMPTY: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_EMPTY); break; - - } - } - else { - switch( GS(tselem->id->name)) { - case ID_SCE: - tselem_draw_icon_uibut(&arg, ICON_SCENE_DATA); break; - case ID_ME: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_MESH); break; - case ID_CU: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CURVE); break; - case ID_MB: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_META); break; - case ID_LT: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LATTICE); break; - case ID_LA: - { - Lamp *la= (Lamp *)tselem->id; - - switch(la->type) { - case LA_LOCAL: - tselem_draw_icon_uibut(&arg, ICON_LAMP_POINT); break; - case LA_SUN: - tselem_draw_icon_uibut(&arg, ICON_LAMP_SUN); break; - case LA_SPOT: - tselem_draw_icon_uibut(&arg, ICON_LAMP_SPOT); break; - case LA_HEMI: - tselem_draw_icon_uibut(&arg, ICON_LAMP_HEMI); break; - case LA_AREA: - tselem_draw_icon_uibut(&arg, ICON_LAMP_AREA); break; - default: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LAMP); break; - } - break; - } - case ID_MA: - tselem_draw_icon_uibut(&arg, ICON_MATERIAL_DATA); break; - case ID_TE: - tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break; - case ID_IM: - tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break; - case ID_SO: - tselem_draw_icon_uibut(&arg, ICON_SPEAKER); break; - case ID_AR: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_ARMATURE); break; - case ID_CA: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CAMERA); break; - case ID_KE: - tselem_draw_icon_uibut(&arg, ICON_SHAPEKEY_DATA); break; - case ID_WO: - tselem_draw_icon_uibut(&arg, ICON_WORLD_DATA); break; - case ID_AC: - tselem_draw_icon_uibut(&arg, ICON_ACTION); break; - case ID_NLA: - tselem_draw_icon_uibut(&arg, ICON_NLA); break; - case ID_TXT: - tselem_draw_icon_uibut(&arg, ICON_SCRIPT); break; - case ID_GR: - tselem_draw_icon_uibut(&arg, ICON_GROUP); break; - case ID_LI: - tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break; - } - } -} - -static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int xmax, int *offsx, int ys) -{ - TreeElement *te; - TreeStoreElem *tselem; - int active; - - for(te= lb->first; te; te= te->next) { - - /* exit drawing early */ - if((*offsx) - UI_UNIT_X > xmax) - break; - - tselem= TREESTORE(te); - - /* object hierarchy always, further constrained on level */ - if(level<1 || (tselem->type==0 && te->idcode==ID_OB)) { - - /* active blocks get white circle */ - if(tselem->type==0) { - if(te->idcode==ID_OB) active= (OBACT==(Object *)tselem->id); - else if(scene->obedit && scene->obedit->data==tselem->id) active= 1; // XXX use context? - else active= tree_element_active(C, scene, soops, te, 0); - } - else active= tree_element_type_active(NULL, scene, soops, te, tselem, 0); - - if(active) { - float ufac= UI_UNIT_X/20.0f; - - uiSetRoundBox(15); - glColor4ub(255, 255, 255, 100); - uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); - glEnable(GL_BLEND); /* roundbox disables */ - } - - tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); - te->xs= (float)*offsx; - te->ys= (float)ys; - te->xend= (short)*offsx+UI_UNIT_X; - te->flag |= TE_ICONROW; // for click - - (*offsx) += UI_UNIT_X; - } - - /* this tree element always has same amount of branches, so dont draw */ - if(tselem->type!=TSE_R_LAYER) - outliner_draw_iconrow(C, block, scene, soops, &te->subtree, level+1, xmax, offsx, ys); - } - -} - -/* closed tree element */ -static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) -{ - TreeElement *ten; - - /* store coord and continue, we need coordinates for elements outside view too */ - te->xs= (float)startx; - te->ys= (float)(*starty); - - for(ten= te->subtree.first; ten; ten= ten->next) { - outliner_set_coord_tree_element(soops, ten, startx+UI_UNIT_X, starty); - } -} - - -static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty) -{ - TreeElement *ten; - TreeStoreElem *tselem; - float ufac= UI_UNIT_X/20.0f; - int offsx= 0, active=0; // active=1 active obj, else active data - - tselem= TREESTORE(te); - - if(*starty+2*UI_UNIT_Y >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) { - int xmax= ar->v2d.cur.xmax; - - /* icons can be ui buts, we dont want it to overlap with restrict */ - if((soops->flag & SO_HIDE_RESTRICTCOLS)==0) - xmax-= OL_TOGW+UI_UNIT_X; - - glEnable(GL_BLEND); - - /* colors for active/selected data */ - if(tselem->type==0) { - if(te->idcode==ID_SCE) { - if(tselem->id == (ID *)scene) { - glColor4ub(255, 255, 255, 100); - active= 2; - } - } - else if(te->idcode==ID_GR) { - Group *gr = (Group *)tselem->id; - - if(group_select_flag(gr)) { - char col[4]; - UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3]= 100; - glColor4ubv((GLubyte *)col); - - active= 2; - } - } - else if(te->idcode==ID_OB) { - Object *ob= (Object *)tselem->id; - - if(ob==OBACT || (ob->flag & SELECT)) { - char col[4]= {0, 0, 0, 0}; - - /* outliner active ob: always white text, circle color now similar to view3d */ - - active= 2; /* means it draws a color circle */ - if(ob==OBACT) { - if(ob->flag & SELECT) { - UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col); - col[3]= 100; - } - - active= 1; /* means it draws white text */ - } - else if(ob->flag & SELECT) { - UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3]= 100; - } - - glColor4ubv((GLubyte *)col); - } - - } - else if(scene->obedit && scene->obedit->data==tselem->id) { - glColor4ub(255, 255, 255, 100); - active= 2; - } - else { - if(tree_element_active(C, scene, soops, te, 0)) { - glColor4ub(220, 220, 255, 100); - active= 2; - } - } - } - else { - if( tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active= 2; - glColor4ub(220, 220, 255, 100); - } - - /* active circle */ - if(active) { - uiSetRoundBox(15); - uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); - glEnable(GL_BLEND); /* roundbox disables it */ - - te->flag |= TE_ACTIVE; // for lookup in display hierarchies - } - - /* open/close icon, only when sublevels, except for scene */ - if(te->subtree.first || (tselem->type==0 && te->idcode==ID_SCE) || (te->flag & TE_LAZY_CLOSED)) { - int icon_x; - if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) - icon_x = startx; - else - icon_x = startx+5*ufac; - - // icons a bit higher - if(tselem->flag & TSE_CLOSED) - UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT); - else - UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN); - } - offsx+= UI_UNIT_X; - - /* datatype icon */ - - if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { - // icons a bit higher - tselem_draw_icon(block, xmax, (float)startx+offsx - 0.5f*ufac, (float)*starty+2.0f*ufac, tselem, te, 1.0f); - - offsx+= UI_UNIT_X; - } - else - offsx+= 2*ufac; - - if(tselem->type==0 && tselem->id->lib) { - glPixelTransferf(GL_ALPHA_SCALE, 0.5f); - if(tselem->id->flag & LIB_INDIRECT) - UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_INDIRECT); - else - UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_DIRECT); - glPixelTransferf(GL_ALPHA_SCALE, 1.0f); - offsx+= UI_UNIT_X; - } - glDisable(GL_BLEND); - - /* name */ - if(active==1) UI_ThemeColor(TH_TEXT_HI); - else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f); - else UI_ThemeColor(TH_TEXT); - - UI_DrawString(startx+offsx, *starty+5*ufac, te->name); - - offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name)); - - /* closed item, we draw the icons, not when it's a scene, or master-server list though */ - if(tselem->flag & TSE_CLOSED) { - if(te->subtree.first) { - if(tselem->type==0 && te->idcode==ID_SCE); - else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */ - int tempx= startx+offsx; - - // divider - UI_ThemeColorShade(TH_BACK, -40); - glRecti(tempx -10, *starty+4, tempx -8, *starty+UI_UNIT_Y-4); - - glEnable(GL_BLEND); - glPixelTransferf(GL_ALPHA_SCALE, 0.5); - - outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty+2); - - glPixelTransferf(GL_ALPHA_SCALE, 1.0); - glDisable(GL_BLEND); - } - } - } - } - /* store coord and continue, we need coordinates for elements outside view too */ - te->xs= (float)startx; - te->ys= (float)*starty; - te->xend= startx+offsx; - - if((tselem->flag & TSE_CLOSED)==0) { - *starty-= UI_UNIT_Y; - - for(ten= te->subtree.first; ten; ten= ten->next) - outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+UI_UNIT_X, starty); - } - else { - for(ten= te->subtree.first; ten; ten= ten->next) - outliner_set_coord_tree_element(soops, te, startx, starty); - - *starty-= UI_UNIT_Y; - } -} - -static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, int *starty) -{ - TreeElement *te; - TreeStoreElem *tselem; - int y1, y2; - - if(lb->first==NULL) return; - - y1=y2= *starty; /* for vertical lines between objects */ - for(te=lb->first; te; te= te->next) { - y2= *starty; - tselem= TREESTORE(te); - - /* horizontal line? */ - if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE)) - glRecti(startx, *starty, startx+UI_UNIT_X, *starty-1); - - *starty-= UI_UNIT_Y; - - if((tselem->flag & TSE_CLOSED)==0) - outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty); - } - - /* vertical line */ - te= lb->last; - if(te->parent || lb->first!=lb->last) { - tselem= TREESTORE(te); - if(tselem->type==0 && te->idcode==ID_OB) { - - glRecti(startx, y1+UI_UNIT_Y, startx+1, y2); - } - } -} - -static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - - /* selection status */ - if((tselem->flag & TSE_CLOSED)==0) - if(tselem->type == TSE_RNA_STRUCT) - glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1); - - *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) { - outliner_draw_struct_marks(ar, soops, &te->subtree, starty); - if(tselem->type == TSE_RNA_STRUCT) - fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y); - } - } -} - -static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - - /* selection status */ - if(tselem->flag & TSE_SELECTED) { - glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); - } - *starty-= UI_UNIT_Y; - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty); - } -} - - -static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops) -{ - TreeElement *te; - int starty, startx; - float col[4]; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once - - if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { - /* struct marks */ - UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); - //UI_ThemeColorShade(TH_BACK, -20); - starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; - outliner_draw_struct_marks(ar, soops, &soops->tree, &starty); - } - - /* always draw selection fill before hierarchy */ - UI_GetThemeColor3fv(TH_BACK, col); - glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); - starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; - outliner_draw_selection(ar, soops, &soops->tree, &starty); - - // grey hierarchy lines - UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.4f); - starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y/2-OL_Y_OFFSET; - startx= 6; - outliner_draw_hierarchy(soops, &soops->tree, startx, &starty); - - // items themselves - starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; - startx= 0; - for(te= soops->tree.first; te; te= te->next) { - outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty); - } -} - - -static void outliner_back(ARegion *ar) -{ - int ystart; - - UI_ThemeColorShade(TH_BACK, 6); - ystart= (int)ar->v2d.tot.ymax; - ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; - - while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { - glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+UI_UNIT_Y); - ystart-= 2*UI_UNIT_Y; - } -} - -static void outliner_draw_restrictcols(ARegion *ar) -{ - int ystart; - - /* background underneath */ - UI_ThemeColor(TH_BACK); - glRecti((int)ar->v2d.cur.xmax-OL_TOGW, (int)ar->v2d.cur.ymin-V2D_SCROLL_HEIGHT-1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (int)ar->v2d.cur.ymax); - - UI_ThemeColorShade(TH_BACK, 6); - ystart= (int)ar->v2d.tot.ymax; - ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; - - while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { - glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+UI_UNIT_Y); - ystart-= 2*UI_UNIT_Y; - } - - UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); - - /* view */ - fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, - ar->v2d.cur.ymax, - ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, - ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); - - /* render */ - fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, - ar->v2d.cur.ymax, - ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, - ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); - - /* render */ - fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, - ar->v2d.cur.ymax, - ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, - ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); -} - -static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2) -{ - Scene *scene = (Scene *)poin; - Object *ob = (Object *)poin2; - - if(!common_restrict_check(C, ob)) return; - - /* deselect objects that are invisible */ - if (ob->restrictflag & OB_RESTRICT_VIEW) { - /* Ouch! There is no backwards pointer from Object to Base, - * so have to do loop to find it. */ - ED_base_object_select(object_in_scene(ob, scene), BA_DESELECT); - } - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - -} - -static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2) -{ - Scene *scene = (Scene *)poin; - Object *ob = (Object *)poin2; - - if(!common_restrict_check(C, ob)) return; - - /* if select restriction has just been turned on */ - if (ob->restrictflag & OB_RESTRICT_SELECT) { - /* Ouch! There is no backwards pointer from Object to Base, - * so have to do loop to find it. */ - ED_base_object_select(object_in_scene(ob, scene), BA_DESELECT); - } - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); - -} - -static void restrictbutton_rend_cb(bContext *C, void *poin, void *UNUSED(poin2)) -{ - WM_event_add_notifier(C, NC_SCENE|ND_OB_RENDER, poin); -} - -static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2)) -{ - WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, poin); -} - -static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *poin2) -{ - Object *ob = (Object *)poin2; - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); -} - -static void restrictbutton_bone_cb(bContext *C, void *UNUSED(poin), void *poin2) -{ - Bone *bone= (Bone *)poin2; - if(bone && (bone->flag & BONE_HIDDEN_P)) - bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); -} - -static void restrictbutton_ebone_cb(bContext *C, void *UNUSED(poin), void *poin2) -{ - EditBone *ebone= (EditBone *)poin2; - if(ebone && (ebone->flag & BONE_HIDDEN_A)) - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); -} - -static int group_restrict_flag(Group *gr, int flag) -{ - GroupObject *gob; - - for(gob= gr->gobject.first; gob; gob= gob->next) { - if((gob->ob->restrictflag & flag) == 0) - return 0; - } - - return 1; -} - -static int group_select_flag(Group *gr) -{ - GroupObject *gob; - - for(gob= gr->gobject.first; gob; gob= gob->next) - if((gob->ob->flag & SELECT)) - return 1; - - return 0; -} - -static void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag) -{ - Scene *scene = (Scene *)poin; - GroupObject *gob; - Group *gr = (Group *)poin2; - - if(group_restrict_flag(gr, flag)) { - for(gob= gr->gobject.first; gob; gob= gob->next) { - gob->ob->restrictflag &= ~flag; - - if(flag==OB_RESTRICT_VIEW) - if(gob->ob->flag & SELECT) - ED_base_object_select(object_in_scene(gob->ob, scene), BA_DESELECT); - } - } - else { - for(gob= gr->gobject.first; gob; gob= gob->next) { - /* not in editmode */ - if(scene->obedit!=gob->ob) { - gob->ob->restrictflag |= flag; - - if(flag==OB_RESTRICT_VIEW) - if((gob->ob->flag & SELECT) == 0) - ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); - } - } - } -} - -static void restrictbutton_gr_restrict_view(bContext *C, void *poin, void *poin2) -{ - restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_VIEW); - WM_event_add_notifier(C, NC_GROUP, NULL); -} -static void restrictbutton_gr_restrict_select(bContext *C, void *poin, void *poin2) -{ - restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_SELECT); - WM_event_add_notifier(C, NC_GROUP, NULL); -} -static void restrictbutton_gr_restrict_render(bContext *C, void *poin, void *poin2) -{ - restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_RENDER); - WM_event_add_notifier(C, NC_GROUP, NULL); -} - - -static void namebutton_cb(bContext *C, void *tsep, char *oldname) -{ - SpaceOops *soops= CTX_wm_space_outliner(C); - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - TreeStore *ts= soops->treestore; - TreeStoreElem *tselem= tsep; - - if(ts && tselem) { - TreeElement *te= outliner_find_tse(soops, tselem); - - if(tselem->type==0) { - test_idbutton(tselem->id->name+2); // library.c, unique name and alpha sort - - switch(GS(tselem->id->name)) { - case ID_MA: - WM_event_add_notifier(C, NC_MATERIAL, NULL); break; - case ID_TE: - WM_event_add_notifier(C, NC_TEXTURE, NULL); break; - case ID_IM: - WM_event_add_notifier(C, NC_IMAGE, NULL); break; - case ID_SCE: - WM_event_add_notifier(C, NC_SCENE, NULL); break; - default: - WM_event_add_notifier(C, NC_ID|NA_RENAME, NULL); break; - } - /* Check the library target exists */ - if (te->idcode == ID_LI) { - char expanded[FILE_MAXDIR + FILE_MAXFILE]; - BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE); - BLI_path_abs(expanded, G.main->name); - if (!BLI_exists(expanded)) { - error("This path does not exist, correct this before saving"); - } - } - } - else { - switch(tselem->type) { - case TSE_DEFGROUP: - defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object - break; - case TSE_NLA_ACTION: - test_idbutton(tselem->id->name+2); - break; - case TSE_EBONE: - { - bArmature *arm= (bArmature *)tselem->id; - if(arm->edbo) { - EditBone *ebone= te->directdata; - char newname[sizeof(ebone->name)]; - - /* restore bone name */ - BLI_strncpy(newname, ebone->name, sizeof(ebone->name)); - BLI_strncpy(ebone->name, oldname, sizeof(ebone->name)); - ED_armature_bone_rename(obedit->data, oldname, newname); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, OBACT); - } - } - break; - - case TSE_BONE: - { - Bone *bone= te->directdata; - Object *ob; - char newname[sizeof(bone->name)]; - - // always make current object active - tree_element_set_active_object(C, scene, soops, te, 1); - ob= OBACT; - - /* restore bone name */ - BLI_strncpy(newname, bone->name, sizeof(bone->name)); - BLI_strncpy(bone->name, oldname, sizeof(bone->name)); - ED_armature_bone_rename(ob->data, oldname, newname); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); - } - break; - case TSE_POSE_CHANNEL: - { - bPoseChannel *pchan= te->directdata; - Object *ob; - char newname[sizeof(pchan->name)]; - - // always make current object active - tree_element_set_active_object(C, scene, soops, te, 1); - ob= OBACT; - - /* restore bone name */ - BLI_strncpy(newname, pchan->name, sizeof(pchan->name)); - BLI_strncpy(pchan->name, oldname, sizeof(pchan->name)); - ED_armature_bone_rename(ob->data, oldname, newname); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); - } - break; - case TSE_POSEGRP: - { - Object *ob= (Object *)tselem->id; // id = object - bActionGroup *grp= te->directdata; - - BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name)); - WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); - } - break; - case TSE_R_LAYER: - break; - } - } - tselem->flag &= ~TSE_TEXTBUT; - } -} - -static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, ListBase *lb) -{ - uiBut *bt; - TreeElement *te; - TreeStoreElem *tselem; - Object *ob = NULL; - Group *gr = NULL; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { - /* objects have toggle-able restriction flags */ - if(tselem->type==0 && te->idcode==ID_OB) { - PointerRNA ptr; - - ob = (Object *)tselem->id; - RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr); - - uiBlockSetEmboss(block, UI_EMBOSSN); - bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, - &ptr, "hide", -1, 0, 0, -1, -1, NULL); - uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); - - bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, - &ptr, "hide_select", -1, 0, 0, -1, -1, NULL); - uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); - - bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, - &ptr, "hide_render", -1, 0, 0, -1, -1, NULL); - uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); - - uiBlockSetEmboss(block, UI_EMBOSS); - - } - if(tselem->type==0 && te->idcode==ID_GR){ - int restrict_bool; - gr = (Group *)tselem->id; - - uiBlockSetEmboss(block, UI_EMBOSSN); - - restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); - uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); - - restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); - uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); - - restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); - uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); - - uiBlockSetEmboss(block, UI_EMBOSS); - } - /* scene render layers and passes have toggle-able flags too! */ - else if(tselem->type==TSE_R_LAYER) { - uiBlockSetEmboss(block, UI_EMBOSSN); - - bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer"); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - - uiBlockSetEmboss(block, UI_EMBOSS); - } - else if(tselem->type==TSE_R_PASS) { - int *layflag= te->directdata; - int passflag= 1<<tselem->nr; - - uiBlockSetEmboss(block, UI_EMBOSSN); - - - bt= uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT-1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Render this Pass"); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - - layflag++; /* is lay_xor */ - if(ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) - bt= uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag)?ICON_DOT:ICON_BLANK1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined"); - uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); - - 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, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); - uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); - - bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability"); - uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); - } - 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, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); - uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone); - - bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); - uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); - } - else if(tselem->type==TSE_EBONE) { - EditBone *ebone= (EditBone *)te->directdata; - - uiBlockSetEmboss(block, UI_EMBOSSN); - bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); - uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone); - - bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); - uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL); - } - } - - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree); - } -} - -static void outliner_draw_rnacols(ARegion *ar, int sizex) -{ - View2D *v2d= &ar->v2d; - - float miny = v2d->cur.ymin-V2D_SCROLL_HEIGHT; - if(miny<v2d->tot.ymin) miny = v2d->tot.ymin; - - UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); - - /* draw column separator lines */ - fdrawline((float)sizex, - v2d->cur.ymax, - (float)sizex, - miny); - - fdrawline((float)sizex+OL_RNA_COL_SIZEX, - v2d->cur.ymax, - (float)sizex+OL_RNA_COL_SIZEX, - miny); -} - -static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - PointerRNA *ptr; - PropertyRNA *prop; - - uiBlockSetEmboss(block, UI_EMBOSST); - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { - if(tselem->type == TSE_RNA_PROPERTY) { - ptr= &te->rnaptr; - prop= te->directdata; - - if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0)) - uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); - } - else if(tselem->type == TSE_RNA_ARRAY_ELEM) { - ptr= &te->rnaptr; - prop= te->directdata; - - uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); - } - } - - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); - } -} - -static void operator_call_cb(struct bContext *UNUSED(C), void *arg_kmi, void *arg2) -{ - wmOperatorType *ot= arg2; - wmKeyMapItem *kmi= arg_kmi; - - if(ot) - BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME); -} - -static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(arg_kmi), const char *str, uiSearchItems *items) -{ - wmOperatorType *ot = WM_operatortype_first(); - - for(; ot; ot= ot->next) { - - if(BLI_strcasestr(ot->idname, str)) { - char name[OP_MAX_TYPENAME]; - - /* display name for menu */ - WM_operator_py_idname(name, ot->idname); - - if(0==uiSearchItemAdd(items, name, ot, 0)) - break; - } - } -} - -/* operator Search browse menu, open */ -static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) -{ - static char search[OP_MAX_TYPENAME]; - wmEvent event; - wmWindow *win= CTX_wm_window(C); - wmKeyMapItem *kmi= arg_kmi; - wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0); - uiBlock *block; - uiBut *but; - - /* clear initial search string, then all items show */ - search[0]= 0; - - block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); - uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); - - /* fake button, it holds space for search items */ - uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); - - but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, ""); - uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); - - uiBoundsBlock(block, 6); - uiBlockSetDirection(block, UI_DOWN); - uiEndBlock(C, block); - - event= *(win->eventstate); /* XXX huh huh? make api call */ - event.type= EVT_BUT_OPEN; - event.val= KM_PRESS; - event.customdata= but; - event.customdatafree= FALSE; - wm_event_add(win, &event); - - return block; -} - -#define OL_KM_KEYBOARD 0 -#define OL_KM_MOUSE 1 -#define OL_KM_TWEAK 2 -#define OL_KM_SPECIALS 3 - -static short keymap_menu_type(short type) -{ - if(ISKEYBOARD(type)) return OL_KM_KEYBOARD; - if(ISTWEAK(type)) return OL_KM_TWEAK; - if(ISMOUSE(type)) return OL_KM_MOUSE; -// return OL_KM_SPECIALS; - return 0; -} - -static const char *keymap_type_menu(void) -{ - static const char string[]= - "Event Type%t" - "|Keyboard%x" STRINGIFY(OL_KM_KEYBOARD) - "|Mouse%x" STRINGIFY(OL_KM_MOUSE) - "|Tweak%x" STRINGIFY(OL_KM_TWEAK) -// "|Specials%x" STRINGIFY(OL_KM_SPECIALS) - ; - - return string; -} - -static const char *keymap_mouse_menu(void) -{ - static const char string[]= - "Mouse Event%t" - "|Left Mouse%x" STRINGIFY(LEFTMOUSE) - "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) - "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) - "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) - "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) - "|Button4 Mouse%x" STRINGIFY(BUTTON4MOUSE) - "|Button5 Mouse%x" STRINGIFY(BUTTON5MOUSE) - "|Action Mouse%x" STRINGIFY(ACTIONMOUSE) - "|Select Mouse%x" STRINGIFY(SELECTMOUSE) - "|Mouse Move%x" STRINGIFY(MOUSEMOVE) - "|Wheel Up%x" STRINGIFY(WHEELUPMOUSE) - "|Wheel Down%x" STRINGIFY(WHEELDOWNMOUSE) - "|Wheel In%x" STRINGIFY(WHEELINMOUSE) - "|Wheel Out%x" STRINGIFY(WHEELOUTMOUSE) - "|Mouse/Trackpad Pan%x" STRINGIFY(MOUSEPAN) - "|Mouse/Trackpad Zoom%x" STRINGIFY(MOUSEZOOM) - "|Mouse/Trackpad Rotate%x" STRINGIFY(MOUSEROTATE) - ; - - return string; -} - -static const char *keymap_tweak_menu(void) -{ - static const char string[]= - "Tweak Event%t" - "|Left Mouse%x" STRINGIFY(EVT_TWEAK_L) - "|Middle Mouse%x" STRINGIFY(EVT_TWEAK_M) - "|Right Mouse%x" STRINGIFY(EVT_TWEAK_R) - "|Action Mouse%x" STRINGIFY(EVT_TWEAK_A) - "|Select Mouse%x" STRINGIFY(EVT_TWEAK_S) - ; - - return string; -} - -static const char *keymap_tweak_dir_menu(void) -{ - static const char string[]= - "Tweak Direction%t" - "|Any%x" STRINGIFY(KM_ANY) - "|North%x" STRINGIFY(EVT_GESTURE_N) - "|North-East%x" STRINGIFY(EVT_GESTURE_NE) - "|East%x" STRINGIFY(EVT_GESTURE_E) - "|Sout-East%x" STRINGIFY(EVT_GESTURE_SE) - "|South%x" STRINGIFY(EVT_GESTURE_S) - "|South-West%x" STRINGIFY(EVT_GESTURE_SW) - "|West%x" STRINGIFY(EVT_GESTURE_W) - "|North-West%x" STRINGIFY(EVT_GESTURE_NW) - ; - - return string; -} - - -static void keymap_type_cb(bContext *C, void *kmi_v, void *UNUSED(arg_v)) -{ - wmKeyMapItem *kmi= kmi_v; - short maptype= keymap_menu_type(kmi->type); - - if(maptype!=kmi->maptype) { - switch(kmi->maptype) { - case OL_KM_KEYBOARD: - kmi->type= AKEY; - kmi->val= KM_PRESS; - break; - case OL_KM_MOUSE: - kmi->type= LEFTMOUSE; - kmi->val= KM_PRESS; - break; - case OL_KM_TWEAK: - kmi->type= EVT_TWEAK_L; - kmi->val= KM_ANY; - break; - case OL_KM_SPECIALS: - kmi->type= AKEY; - kmi->val= KM_PRESS; - } - ED_region_tag_redraw(CTX_wm_region(C)); - } -} - -static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) -{ - TreeElement *te; - TreeStoreElem *tselem; - - uiBlockSetEmboss(block, UI_EMBOSST); - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { - uiBut *but; - const char *str; - int xstart= 240; - int butw1= UI_UNIT_X; /* operator */ - int butw2= 90; /* event type, menus */ - int butw3= 43; /* modifiers */ - - if(tselem->type == TSE_KEYMAP_ITEM) { - wmKeyMapItem *kmi= te->directdata; - - /* modal map? */ - if(kmi->propvalue); - else { - uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, UI_UNIT_Y-1, "Assign new Operator"); - } - xstart+= butw1+10; - - /* map type button */ - kmi->maptype= keymap_menu_type(kmi->type); - - str= keymap_type_menu(); - but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->maptype, 0, 0, 0, 0, "Event type"); - uiButSetFunc(but, keymap_type_cb, kmi, NULL); - xstart+= butw2+5; - - /* edit actual event */ - switch(kmi->maptype) { - case OL_KM_KEYBOARD: - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, "Key code"); - xstart+= butw2+5; - break; - case OL_KM_MOUSE: - str= keymap_mouse_menu(); - uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Mouse button"); - xstart+= butw2+5; - break; - case OL_KM_TWEAK: - str= keymap_tweak_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture"); - xstart+= butw2+5; - str= keymap_tweak_dir_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction"); - xstart+= butw2+5; - break; - } - - /* modifiers */ - uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, UI_UNIT_Y-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5; - uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - xstart+= 5; - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->keymodifier, "Key Modifier code"); - xstart+= butw3+5; - - /* rna property */ - if(kmi->ptr && kmi->ptr->data) { - uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2; - } - - (void)xstart; - } - } - - if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree); - } -} - - -static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) -{ - uiBut *bt; - TreeElement *te; - TreeStoreElem *tselem; - int spx, dx, len; - - for(te= lb->first; te; te= te->next) { - tselem= TREESTORE(te); - if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { - - if(tselem->flag & TSE_TEXTBUT) { - - /* If we add support to rename Sequence. - * need change this. - */ - if(tselem->type == TSE_POSE_BASE) continue; // prevent crash when trying to rename 'pose' entry of armature - - if(tselem->type==TSE_EBONE) len = sizeof(((EditBone*) 0)->name); - else if (tselem->type==TSE_MODIFIER) len = sizeof(((ModifierData*) 0)->name); - else if(tselem->id && GS(tselem->id->name)==ID_LI) len = sizeof(((Library*) 0)->name); - else len= MAX_ID_NAME-2; - - - dx= (int)UI_GetStringWidth(te->name); - if(dx<100) dx= 100; - spx=te->xs+2*UI_UNIT_X-4; - if(spx+dx+10>ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax-spx-10; - - bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, UI_UNIT_Y-1, (void *)te->name, 1.0, (float)len, 0, 0, ""); - uiButSetRenameFunc(bt, namebutton_cb, tselem); - - /* returns false if button got removed */ - if( 0 == uiButActiveOnly(C, block, bt) ) - tselem->flag &= ~TSE_TEXTBUT; - } - } - - if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(C, block, ar, soops, &te->subtree); - } -} - -void draw_outliner(const bContext *C) -{ - Main *mainvar= CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - ARegion *ar= CTX_wm_region(C); - View2D *v2d= &ar->v2d; - SpaceOops *soops= CTX_wm_space_outliner(C); - uiBlock *block; - int sizey= 0, sizex= 0, sizex_rna= 0; - - outliner_build_tree(mainvar, scene, soops); // always - - /* get extents of data */ - outliner_height(soops, &soops->tree, &sizey); - - if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) { - /* RNA has two columns: - * - column 1 is (max_width + OL_RNA_COL_SPACEX) or - * (OL_RNA_COL_X), whichever is wider... - * - column 2 is fixed at OL_RNA_COL_SIZEX - * - * (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100) - */ - - /* get actual width of column 1 */ - outliner_rna_width(soops, &soops->tree, &sizex_rna, 0); - sizex_rna= MAX2(OL_RNA_COLX, sizex_rna+OL_RNA_COL_SPACEX); - - /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */ - if (soops->outlinevis == SO_KEYMAP) - sizex= sizex_rna + OL_RNA_COL_SIZEX*3 + 50; // XXX this is only really a quick hack to make this wide enough... - else - sizex= sizex_rna + OL_RNA_COL_SIZEX + 50; - } - else { - /* width must take into account restriction columns (if visible) so that entries will still be visible */ - //outliner_width(soops, &soops->tree, &sizex); - outliner_rna_width(soops, &soops->tree, &sizex, 0); // XXX should use outliner_width instead when te->xend will be set correctly... - - /* constant offset for restriction columns */ - // XXX this isn't that great yet... - if ((soops->flag & SO_HIDE_RESTRICTCOLS)==0) - sizex += OL_TOGW*3; - } - - /* tweak to display last line (when list bigger than window) */ - sizey += V2D_SCROLL_HEIGHT; - - /* adds vertical offset */ - sizey += OL_Y_OFFSET; - - /* update size of tot-rect (extents of data/viewable area) */ - UI_view2d_totRect_set(v2d, sizex, sizey); - - /* force display to pixel coords */ - v2d->flag |= (V2D_PIXELOFS_X|V2D_PIXELOFS_Y); - /* set matrix for 2d-view controls */ - UI_view2d_view_ortho(v2d); - - /* draw outliner stuff (background, hierachy lines and names) */ - outliner_back(ar); - block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS); - outliner_draw_tree((bContext *)C, block, scene, ar, soops); - - if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { - /* draw rna buttons */ - outliner_draw_rnacols(ar, sizex_rna); - outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree); - } - else if(soops->outlinevis == SO_KEYMAP) { - outliner_draw_keymapbuts(block, ar, soops, &soops->tree); - } - else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { - /* draw restriction columns */ - outliner_draw_restrictcols(ar); - outliner_draw_restrictbuts(block, scene, ar, soops, &soops->tree); - } - - /* draw edit buttons if nessecery */ - outliner_buttons(C, block, ar, soops, &soops->tree); - - uiEndBlock(C, block); - uiDrawBlock(C, block); - - /* clear flag that allows quick redraws */ - soops->storeflag &= ~SO_TREESTORE_REDRAW; -} - diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c new file mode 100644 index 00000000000..83b617973be --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -0,0 +1,1673 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_outliner/outliner_draw.c + * \ingroup spoutliner + */ + +#include <string.h> +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_world_types.h" +#include "DNA_sequence_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_modifier.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_sequencer.h" + +#include "BLI_ghash.h" + +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "outliner_intern.h" + +/* ****************************************************** */ +/* Tree Size Functions */ + +static void outliner_height(SpaceOops *soops, ListBase *lb, int *h) +{ + TreeElement *te= lb->first; + while(te) { + TreeStoreElem *tselem= TREESTORE(te); + if((tselem->flag & TSE_CLOSED)==0) + outliner_height(soops, &te->subtree, h); + (*h) += UI_UNIT_Y; + te= te->next; + } +} + +#if 0 // XXX this is currently disabled until te->xend is set correctly +static void outliner_width(SpaceOops *soops, ListBase *lb, int *w) +{ + TreeElement *te= lb->first; + while(te) { +// TreeStoreElem *tselem= TREESTORE(te); + + // XXX fixme... te->xend is not set yet + if(tselem->flag & TSE_CLOSED) { + if (te->xend > *w) + *w = te->xend; + } + outliner_width(soops, &te->subtree, w); + te= te->next; + } +} +#endif + +static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int startx) +{ + TreeElement *te= lb->first; + while(te) { + TreeStoreElem *tselem= TREESTORE(te); + // XXX fixme... (currently, we're using a fixed length of 100)! + /*if(te->xend) { + if(te->xend > *w) + *w = te->xend; + }*/ + if(startx+100 > *w) + *w = startx+100; + + if((tselem->flag & TSE_CLOSED)==0) + outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X); + te= te->next; + } +} + +/* ****************************************************** */ + +static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2) +{ + Scene *scene = (Scene *)poin; + Object *ob = (Object *)poin2; + + if(!common_restrict_check(C, ob)) return; + + /* deselect objects that are invisible */ + if (ob->restrictflag & OB_RESTRICT_VIEW) { + /* Ouch! There is no backwards pointer from Object to Base, + * so have to do loop to find it. */ + ED_base_object_select(object_in_scene(ob, scene), BA_DESELECT); + } + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + +} + +static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2) +{ + Scene *scene = (Scene *)poin; + Object *ob = (Object *)poin2; + + if(!common_restrict_check(C, ob)) return; + + /* if select restriction has just been turned on */ + if (ob->restrictflag & OB_RESTRICT_SELECT) { + /* Ouch! There is no backwards pointer from Object to Base, + * so have to do loop to find it. */ + ED_base_object_select(object_in_scene(ob, scene), BA_DESELECT); + } + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + +} + +static void restrictbutton_rend_cb(bContext *C, void *poin, void *UNUSED(poin2)) +{ + WM_event_add_notifier(C, NC_SCENE|ND_OB_RENDER, poin); +} + +static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2)) +{ + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, poin); +} + +static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *poin2) +{ + Object *ob = (Object *)poin2; + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); +} + +static void restrictbutton_bone_cb(bContext *C, void *UNUSED(poin), void *poin2) +{ + Bone *bone= (Bone *)poin2; + if(bone && (bone->flag & BONE_HIDDEN_P)) + bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); +} + +static void restrictbutton_ebone_cb(bContext *C, void *UNUSED(poin), void *poin2) +{ + EditBone *ebone= (EditBone *)poin2; + if(ebone && (ebone->flag & BONE_HIDDEN_A)) + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); +} + +static int group_restrict_flag(Group *gr, int flag) +{ + GroupObject *gob; + + for(gob= gr->gobject.first; gob; gob= gob->next) { + if((gob->ob->restrictflag & flag) == 0) + return 0; + } + + return 1; +} + +static int group_select_flag(Group *gr) +{ + GroupObject *gob; + + for(gob= gr->gobject.first; gob; gob= gob->next) + if((gob->ob->flag & SELECT)) + return 1; + + return 0; +} + +static void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag) +{ + Scene *scene = (Scene *)poin; + GroupObject *gob; + Group *gr = (Group *)poin2; + + if(group_restrict_flag(gr, flag)) { + for(gob= gr->gobject.first; gob; gob= gob->next) { + gob->ob->restrictflag &= ~flag; + + if(flag==OB_RESTRICT_VIEW) + if(gob->ob->flag & SELECT) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_DESELECT); + } + } + else { + for(gob= gr->gobject.first; gob; gob= gob->next) { + /* not in editmode */ + if(scene->obedit!=gob->ob) { + gob->ob->restrictflag |= flag; + + if(flag==OB_RESTRICT_VIEW) + if((gob->ob->flag & SELECT) == 0) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); + } + } + } +} + +static void restrictbutton_gr_restrict_view(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_VIEW); + WM_event_add_notifier(C, NC_GROUP, NULL); +} +static void restrictbutton_gr_restrict_select(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_SELECT); + WM_event_add_notifier(C, NC_GROUP, NULL); +} +static void restrictbutton_gr_restrict_render(bContext *C, void *poin, void *poin2) +{ + restrictbutton_gr_restrict_flag(poin, poin2, OB_RESTRICT_RENDER); + WM_event_add_notifier(C, NC_GROUP, NULL); +} + + +static void namebutton_cb(bContext *C, void *tsep, char *oldname) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + TreeStore *ts= soops->treestore; + TreeStoreElem *tselem= tsep; + + if(ts && tselem) { + TreeElement *te= outliner_find_tse(soops, tselem); + + if(tselem->type==0) { + test_idbutton(tselem->id->name+2); // library.c, unique name and alpha sort + + switch(GS(tselem->id->name)) { + case ID_MA: + WM_event_add_notifier(C, NC_MATERIAL, NULL); break; + case ID_TE: + WM_event_add_notifier(C, NC_TEXTURE, NULL); break; + case ID_IM: + WM_event_add_notifier(C, NC_IMAGE, NULL); break; + case ID_SCE: + WM_event_add_notifier(C, NC_SCENE, NULL); break; + default: + WM_event_add_notifier(C, NC_ID|NA_RENAME, NULL); break; + } + /* Check the library target exists */ + if (te->idcode == ID_LI) { + char expanded[FILE_MAXDIR + FILE_MAXFILE]; + BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE); + BLI_path_abs(expanded, G.main->name); + if (!BLI_exists(expanded)) { + BKE_report(CTX_wm_reports(C), RPT_ERROR, "This path does not exist, correct this before saving"); + } + } + } + else { + switch(tselem->type) { + case TSE_DEFGROUP: + defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object + break; + case TSE_NLA_ACTION: + test_idbutton(tselem->id->name+2); + break; + case TSE_EBONE: + { + bArmature *arm= (bArmature *)tselem->id; + if(arm->edbo) { + EditBone *ebone= te->directdata; + char newname[sizeof(ebone->name)]; + + /* restore bone name */ + BLI_strncpy(newname, ebone->name, sizeof(ebone->name)); + BLI_strncpy(ebone->name, oldname, sizeof(ebone->name)); + ED_armature_bone_rename(obedit->data, oldname, newname); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, OBACT); + } + } + break; + + case TSE_BONE: + { + Bone *bone= te->directdata; + Object *ob; + char newname[sizeof(bone->name)]; + + // always make current object active + tree_element_active(C, scene, soops, te, 1); // was set_active_object() + ob= OBACT; + + /* restore bone name */ + BLI_strncpy(newname, bone->name, sizeof(bone->name)); + BLI_strncpy(bone->name, oldname, sizeof(bone->name)); + ED_armature_bone_rename(ob->data, oldname, newname); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); + } + break; + case TSE_POSE_CHANNEL: + { + bPoseChannel *pchan= te->directdata; + Object *ob; + char newname[sizeof(pchan->name)]; + + // always make current object active + tree_element_active(C, scene, soops, te, 1); // was set_active_object() + ob= OBACT; + + /* restore bone name */ + BLI_strncpy(newname, pchan->name, sizeof(pchan->name)); + BLI_strncpy(pchan->name, oldname, sizeof(pchan->name)); + ED_armature_bone_rename(ob->data, oldname, newname); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); + } + break; + case TSE_POSEGRP: + { + Object *ob= (Object *)tselem->id; // id = object + bActionGroup *grp= te->directdata; + + BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name)); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); + } + break; + case TSE_R_LAYER: + break; + } + } + tselem->flag &= ~TSE_TEXTBUT; + } +} + +static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, ListBase *lb) +{ + uiBut *bt; + TreeElement *te; + TreeStoreElem *tselem; + Object *ob = NULL; + Group *gr = NULL; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + /* objects have toggle-able restriction flags */ + if(tselem->type==0 && te->idcode==ID_OB) { + PointerRNA ptr; + + ob = (Object *)tselem->id; + RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr); + + uiBlockSetEmboss(block, UI_EMBOSSN); + bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, + &ptr, "hide", -1, 0, 0, -1, -1, NULL); + uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); + + bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, + &ptr, "hide_select", -1, 0, 0, -1, -1, NULL); + uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); + + bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, + &ptr, "hide_render", -1, 0, 0, -1, -1, NULL); + uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); + + uiBlockSetEmboss(block, UI_EMBOSS); + + } + if(tselem->type==0 && te->idcode==ID_GR){ + int restrict_bool; + gr = (Group *)tselem->id; + + uiBlockSetEmboss(block, UI_EMBOSSN); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); + + restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); + uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); + + uiBlockSetEmboss(block, UI_EMBOSS); + } + /* scene render layers and passes have toggle-able flags too! */ + else if(tselem->type==TSE_R_LAYER) { + uiBlockSetEmboss(block, UI_EMBOSSN); + + bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + + uiBlockSetEmboss(block, UI_EMBOSS); + } + else if(tselem->type==TSE_R_PASS) { + int *layflag= te->directdata; + int passflag= 1<<tselem->nr; + + uiBlockSetEmboss(block, UI_EMBOSSN); + + + bt= uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT-1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Render this Pass"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + + layflag++; /* is lay_xor */ + if(ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) + bt= uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag)?ICON_DOT:ICON_BLANK1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined"); + uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); + + 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, 0, ICON_RESTRICT_VIEW_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); + + bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability"); + uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); + } + 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, 0, ICON_RESTRICT_VIEW_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone); + + bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); + } + else if(tselem->type==TSE_EBONE) { + EditBone *ebone= (EditBone *)te->directdata; + + uiBlockSetEmboss(block, UI_EMBOSSN); + bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone); + + bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL); + } + } + + if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree); + } +} + +static void outliner_draw_rnacols(ARegion *ar, int sizex) +{ + View2D *v2d= &ar->v2d; + + float miny = v2d->cur.ymin-V2D_SCROLL_HEIGHT; + if(miny<v2d->tot.ymin) miny = v2d->tot.ymin; + + UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); + + /* draw column separator lines */ + fdrawline((float)sizex, + v2d->cur.ymax, + (float)sizex, + miny); + + fdrawline((float)sizex+OL_RNA_COL_SIZEX, + v2d->cur.ymax, + (float)sizex+OL_RNA_COL_SIZEX, + miny); +} + +static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + PointerRNA *ptr; + PropertyRNA *prop; + + uiBlockSetEmboss(block, UI_EMBOSST); + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(tselem->type == TSE_RNA_PROPERTY) { + ptr= &te->rnaptr; + prop= te->directdata; + + if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0)) + uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); + } + else if(tselem->type == TSE_RNA_ARRAY_ELEM) { + ptr= &te->rnaptr; + prop= te->directdata; + + uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); + } + } + + if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); + } +} + +static void operator_call_cb(struct bContext *UNUSED(C), void *arg_kmi, void *arg2) +{ + wmOperatorType *ot= arg2; + wmKeyMapItem *kmi= arg_kmi; + + if(ot) + BLI_strncpy(kmi->idname, ot->idname, OP_MAX_TYPENAME); +} + +static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(arg_kmi), const char *str, uiSearchItems *items) +{ + GHashIterator *iter= WM_operatortype_iter(); + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + wmOperatorType *ot= BLI_ghashIterator_getValue(iter); + + if(BLI_strcasestr(ot->idname, str)) { + char name[OP_MAX_TYPENAME]; + + /* display name for menu */ + WM_operator_py_idname(name, ot->idname); + + if(0==uiSearchItemAdd(items, name, ot, 0)) + break; + } + } + BLI_ghashIterator_free(iter); +} + +/* operator Search browse menu, open */ +static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) +{ + static char search[OP_MAX_TYPENAME]; + wmEvent event; + wmWindow *win= CTX_wm_window(C); + wmKeyMapItem *kmi= arg_kmi; + wmOperatorType *ot= WM_operatortype_find(kmi->idname, 0); + uiBlock *block; + uiBut *but; + + /* clear initial search string, then all items show */ + search[0]= 0; + + block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); + + /* fake button, it holds space for search items */ + uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, ""); + uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); + + uiBoundsBlock(block, 6); + uiBlockSetDirection(block, UI_DOWN); + uiEndBlock(C, block); + + event= *(win->eventstate); /* XXX huh huh? make api call */ + event.type= EVT_BUT_OPEN; + event.val= KM_PRESS; + event.customdata= but; + event.customdatafree= FALSE; + wm_event_add(win, &event); + + return block; +} + +#define OL_KM_KEYBOARD 0 +#define OL_KM_MOUSE 1 +#define OL_KM_TWEAK 2 +#define OL_KM_SPECIALS 3 + +static short keymap_menu_type(short type) +{ + if(ISKEYBOARD(type)) return OL_KM_KEYBOARD; + if(ISTWEAK(type)) return OL_KM_TWEAK; + if(ISMOUSE(type)) return OL_KM_MOUSE; +// return OL_KM_SPECIALS; + return 0; +} + +static const char *keymap_type_menu(void) +{ + static const char string[]= + "Event Type%t" + "|Keyboard%x" STRINGIFY(OL_KM_KEYBOARD) + "|Mouse%x" STRINGIFY(OL_KM_MOUSE) + "|Tweak%x" STRINGIFY(OL_KM_TWEAK) +// "|Specials%x" STRINGIFY(OL_KM_SPECIALS) + ; + + return string; +} + +static const char *keymap_mouse_menu(void) +{ + static const char string[]= + "Mouse Event%t" + "|Left Mouse%x" STRINGIFY(LEFTMOUSE) + "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) + "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) + "|Middle Mouse%x" STRINGIFY(MIDDLEMOUSE) + "|Right Mouse%x" STRINGIFY(RIGHTMOUSE) + "|Button4 Mouse%x" STRINGIFY(BUTTON4MOUSE) + "|Button5 Mouse%x" STRINGIFY(BUTTON5MOUSE) + "|Action Mouse%x" STRINGIFY(ACTIONMOUSE) + "|Select Mouse%x" STRINGIFY(SELECTMOUSE) + "|Mouse Move%x" STRINGIFY(MOUSEMOVE) + "|Wheel Up%x" STRINGIFY(WHEELUPMOUSE) + "|Wheel Down%x" STRINGIFY(WHEELDOWNMOUSE) + "|Wheel In%x" STRINGIFY(WHEELINMOUSE) + "|Wheel Out%x" STRINGIFY(WHEELOUTMOUSE) + "|Mouse/Trackpad Pan%x" STRINGIFY(MOUSEPAN) + "|Mouse/Trackpad Zoom%x" STRINGIFY(MOUSEZOOM) + "|Mouse/Trackpad Rotate%x" STRINGIFY(MOUSEROTATE) + ; + + return string; +} + +static const char *keymap_tweak_menu(void) +{ + static const char string[]= + "Tweak Event%t" + "|Left Mouse%x" STRINGIFY(EVT_TWEAK_L) + "|Middle Mouse%x" STRINGIFY(EVT_TWEAK_M) + "|Right Mouse%x" STRINGIFY(EVT_TWEAK_R) + "|Action Mouse%x" STRINGIFY(EVT_TWEAK_A) + "|Select Mouse%x" STRINGIFY(EVT_TWEAK_S) + ; + + return string; +} + +static const char *keymap_tweak_dir_menu(void) +{ + static const char string[]= + "Tweak Direction%t" + "|Any%x" STRINGIFY(KM_ANY) + "|North%x" STRINGIFY(EVT_GESTURE_N) + "|North-East%x" STRINGIFY(EVT_GESTURE_NE) + "|East%x" STRINGIFY(EVT_GESTURE_E) + "|Sout-East%x" STRINGIFY(EVT_GESTURE_SE) + "|South%x" STRINGIFY(EVT_GESTURE_S) + "|South-West%x" STRINGIFY(EVT_GESTURE_SW) + "|West%x" STRINGIFY(EVT_GESTURE_W) + "|North-West%x" STRINGIFY(EVT_GESTURE_NW) + ; + + return string; +} + + +static void keymap_type_cb(bContext *C, void *kmi_v, void *UNUSED(arg_v)) +{ + wmKeyMapItem *kmi= kmi_v; + short maptype= keymap_menu_type(kmi->type); + + if(maptype!=kmi->maptype) { + switch(kmi->maptype) { + case OL_KM_KEYBOARD: + kmi->type= AKEY; + kmi->val= KM_PRESS; + break; + case OL_KM_MOUSE: + kmi->type= LEFTMOUSE; + kmi->val= KM_PRESS; + break; + case OL_KM_TWEAK: + kmi->type= EVT_TWEAK_L; + kmi->val= KM_ANY; + break; + case OL_KM_SPECIALS: + kmi->type= AKEY; + kmi->val= KM_PRESS; + } + ED_region_tag_redraw(CTX_wm_region(C)); + } +} + +static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + + uiBlockSetEmboss(block, UI_EMBOSST); + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + uiBut *but; + const char *str; + int xstart= 240; + int butw1= UI_UNIT_X; /* operator */ + int butw2= 90; /* event type, menus */ + int butw3= 43; /* modifiers */ + + if(tselem->type == TSE_KEYMAP_ITEM) { + wmKeyMapItem *kmi= te->directdata; + + /* modal map? */ + if(kmi->propvalue); + else { + uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, UI_UNIT_Y-1, "Assign new Operator"); + } + xstart+= butw1+10; + + /* map type button */ + kmi->maptype= keymap_menu_type(kmi->type); + + str= keymap_type_menu(); + but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->maptype, 0, 0, 0, 0, "Event type"); + uiButSetFunc(but, keymap_type_cb, kmi, NULL); + xstart+= butw2+5; + + /* edit actual event */ + switch(kmi->maptype) { + case OL_KM_KEYBOARD: + uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, "Key code"); + xstart+= butw2+5; + break; + case OL_KM_MOUSE: + str= keymap_mouse_menu(); + uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Mouse button"); + xstart+= butw2+5; + break; + case OL_KM_TWEAK: + str= keymap_tweak_menu(); + uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture"); + xstart+= butw2+5; + str= keymap_tweak_dir_menu(); + uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction"); + xstart+= butw2+5; + break; + } + + /* modifiers */ + uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, UI_UNIT_Y-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5; + uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + xstart+= 5; + uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->keymodifier, "Key Modifier code"); + xstart+= butw3+5; + + /* rna property */ + if(kmi->ptr && kmi->ptr->data) { + uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2; + } + + (void)xstart; + } + } + + if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree); + } +} + + +static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) +{ + uiBut *bt; + TreeElement *te; + TreeStoreElem *tselem; + int spx, dx, len; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + + if(tselem->flag & TSE_TEXTBUT) { + + /* If we add support to rename Sequence. + * need change this. + */ + if(tselem->type == TSE_POSE_BASE) continue; // prevent crash when trying to rename 'pose' entry of armature + + if(tselem->type==TSE_EBONE) len = sizeof(((EditBone*) 0)->name); + else if (tselem->type==TSE_MODIFIER) len = sizeof(((ModifierData*) 0)->name); + else if(tselem->id && GS(tselem->id->name)==ID_LI) len = sizeof(((Library*) 0)->name); + else len= MAX_ID_NAME-2; + + + dx= (int)UI_GetStringWidth(te->name); + if(dx<100) dx= 100; + spx=te->xs+2*UI_UNIT_X-4; + if(spx+dx+10>ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax-spx-10; + + bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, UI_UNIT_Y-1, (void *)te->name, 1.0, (float)len, 0, 0, ""); + uiButSetRenameFunc(bt, namebutton_cb, tselem); + + /* returns false if button got removed */ + if( 0 == uiButActiveOnly(C, block, bt) ) + tselem->flag &= ~TSE_TEXTBUT; + } + } + + if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(C, block, ar, soops, &te->subtree); + } +} + +/* ****************************************************** */ +/* Normal Drawing... */ + +/* make function calls a bit compacter */ +struct DrawIconArg { + uiBlock *block; + ID *id; + int xmax, x, y; + float alpha; +}; + +static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) +{ + /* restrict collumn clip... it has been coded by simply overdrawing, doesnt work for buttons */ + if(arg->x >= arg->xmax) + UI_icon_draw(arg->x, arg->y, icon); + else { + /* XXX investigate: button placement of icons is way different than UI_icon_draw? */ + float ufac= UI_UNIT_X/20.0f; + uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-3.0f*ufac, arg->y, UI_UNIT_X-4.0f*ufac, UI_UNIT_Y-4.0f*ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); + + if(arg->id) + uiButSetDragID(but, arg->id); + } + +} + +static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha) +{ + struct DrawIconArg arg; + + /* make function calls a bit compacter */ + arg.block= block; + arg.id= tselem->id; + arg.xmax= xmax; + arg.x= x; + arg.y= y; + arg.alpha= alpha; + + if(tselem->type) { + switch( tselem->type) { + case TSE_ANIM_DATA: + UI_icon_draw(x, y, ICON_ANIM_DATA); break; // xxx + case TSE_NLA: + UI_icon_draw(x, y, ICON_NLA); break; + case TSE_NLA_TRACK: + UI_icon_draw(x, y, ICON_NLA); break; // XXX + case TSE_NLA_ACTION: + UI_icon_draw(x, y, ICON_ACTION); break; + case TSE_DRIVER_BASE: + +#if 0 // GSOC_PEPPER + + UI_icon_draw(x, y, ICON_DRIVER); break; + +#endif // GSOC_PEPPER + + case TSE_DEFGROUP_BASE: + UI_icon_draw(x, y, ICON_GROUP_VERTEX); break; + case TSE_BONE: + case TSE_EBONE: + UI_icon_draw(x, y, ICON_BONE_DATA); break; + case TSE_CONSTRAINT_BASE: + UI_icon_draw(x, y, ICON_CONSTRAINT); break; + case TSE_MODIFIER_BASE: + UI_icon_draw(x, y, ICON_MODIFIER); break; + case TSE_LINKED_OB: + UI_icon_draw(x, y, ICON_OBJECT_DATA); break; + case TSE_LINKED_PSYS: + UI_icon_draw(x, y, ICON_PARTICLES); break; + case TSE_MODIFIER: + { + Object *ob= (Object *)tselem->id; + ModifierData *md= BLI_findlink(&ob->modifiers, tselem->nr); + switch(md->type) { + case eModifierType_Subsurf: + UI_icon_draw(x, y, ICON_MOD_SUBSURF); break; + case eModifierType_Armature: + UI_icon_draw(x, y, ICON_MOD_ARMATURE); break; + case eModifierType_Lattice: + UI_icon_draw(x, y, ICON_MOD_LATTICE); break; + case eModifierType_Curve: + UI_icon_draw(x, y, ICON_MOD_CURVE); break; + case eModifierType_Build: + UI_icon_draw(x, y, ICON_MOD_BUILD); break; + case eModifierType_Mirror: + UI_icon_draw(x, y, ICON_MOD_MIRROR); break; + case eModifierType_Decimate: + UI_icon_draw(x, y, ICON_MOD_DECIM); break; + case eModifierType_Wave: + UI_icon_draw(x, y, ICON_MOD_WAVE); break; + case eModifierType_Hook: + UI_icon_draw(x, y, ICON_HOOK); break; + case eModifierType_Softbody: + UI_icon_draw(x, y, ICON_MOD_SOFT); break; + case eModifierType_Boolean: + UI_icon_draw(x, y, ICON_MOD_BOOLEAN); break; + case eModifierType_ParticleSystem: + UI_icon_draw(x, y, ICON_MOD_PARTICLES); break; + case eModifierType_ParticleInstance: + UI_icon_draw(x, y, ICON_MOD_PARTICLES); break; + case eModifierType_EdgeSplit: + UI_icon_draw(x, y, ICON_MOD_EDGESPLIT); break; + case eModifierType_Array: + UI_icon_draw(x, y, ICON_MOD_ARRAY); break; + case eModifierType_UVProject: + UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break; + case eModifierType_Displace: + UI_icon_draw(x, y, ICON_MOD_DISPLACE); break; + case eModifierType_Shrinkwrap: + UI_icon_draw(x, y, ICON_MOD_SHRINKWRAP); break; + case eModifierType_Cast: + UI_icon_draw(x, y, ICON_MOD_CAST); break; + case eModifierType_MeshDeform: + UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; + case eModifierType_Bevel: + UI_icon_draw(x, y, ICON_MOD_BEVEL); break; + case eModifierType_Smooth: + UI_icon_draw(x, y, ICON_MOD_SMOOTH); break; + case eModifierType_SimpleDeform: + UI_icon_draw(x, y, ICON_MOD_SIMPLEDEFORM); break; + case eModifierType_Mask: + UI_icon_draw(x, y, ICON_MOD_MASK); break; + case eModifierType_Cloth: + UI_icon_draw(x, y, ICON_MOD_CLOTH); break; + case eModifierType_Explode: + UI_icon_draw(x, y, ICON_MOD_EXPLODE); break; + case eModifierType_Collision: + UI_icon_draw(x, y, ICON_MOD_PHYSICS); break; + case eModifierType_Fluidsim: + UI_icon_draw(x, y, ICON_MOD_FLUIDSIM); break; + case eModifierType_Multires: + UI_icon_draw(x, y, ICON_MOD_MULTIRES); break; + case eModifierType_Smoke: + UI_icon_draw(x, y, ICON_MOD_SMOKE); break; + case eModifierType_Solidify: + UI_icon_draw(x, y, ICON_MOD_SOLIDIFY); break; + case eModifierType_Screw: + UI_icon_draw(x, y, ICON_MOD_SCREW); break; + case eModifierType_DynamicPaint: + UI_icon_draw(x, y, ICON_MOD_DYNAMICPAINT); break; + default: + UI_icon_draw(x, y, ICON_DOT); break; + } + break; + } + case TSE_SCRIPT_BASE: + UI_icon_draw(x, y, ICON_TEXT); break; + case TSE_POSE_BASE: + UI_icon_draw(x, y, ICON_ARMATURE_DATA); break; + case TSE_POSE_CHANNEL: + UI_icon_draw(x, y, ICON_BONE_DATA); break; + case TSE_PROXY: + UI_icon_draw(x, y, ICON_GHOST); break; + case TSE_R_LAYER_BASE: + UI_icon_draw(x, y, ICON_RENDERLAYERS); break; + case TSE_R_LAYER: + UI_icon_draw(x, y, ICON_RENDERLAYERS); break; + case TSE_LINKED_LAMP: + UI_icon_draw(x, y, ICON_LAMP_DATA); break; + case TSE_LINKED_MAT: + UI_icon_draw(x, y, ICON_MATERIAL_DATA); break; + case TSE_POSEGRP_BASE: + UI_icon_draw(x, y, ICON_VERTEXSEL); break; + case TSE_SEQUENCE: + if(te->idcode==SEQ_MOVIE) + UI_icon_draw(x, y, ICON_SEQUENCE); + else if(te->idcode==SEQ_META) + UI_icon_draw(x, y, ICON_DOT); + else if(te->idcode==SEQ_SCENE) + UI_icon_draw(x, y, ICON_SCENE); + else if(te->idcode==SEQ_SOUND) + UI_icon_draw(x, y, ICON_SOUND); + else if(te->idcode==SEQ_IMAGE) + UI_icon_draw(x, y, ICON_IMAGE_COL); + else + UI_icon_draw(x, y, ICON_PARTICLES); + break; + case TSE_SEQ_STRIP: + UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT); + break; + case TSE_SEQUENCE_DUP: + UI_icon_draw(x, y, ICON_OBJECT_DATA); + break; + case TSE_RNA_STRUCT: + if(RNA_struct_is_ID(te->rnaptr.type)) { + arg.id= (ID *)te->rnaptr.data; + tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type)); + } + else + UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type)); + break; + default: + UI_icon_draw(x, y, ICON_DOT); break; + } + } + else if (GS(tselem->id->name) == ID_OB) { + Object *ob= (Object *)tselem->id; + switch (ob->type) { + case OB_LAMP: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LAMP); break; + case OB_MESH: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_MESH); break; + case OB_CAMERA: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CAMERA); break; + case OB_CURVE: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CURVE); break; + case OB_MBALL: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_META); break; + case OB_LATTICE: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LATTICE); break; + case OB_ARMATURE: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_ARMATURE); break; + case OB_FONT: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_FONT); break; + case OB_SURF: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SURFACE); break; + +#if 0 // GSOC_PEPPER + + case OB_SPEAKER: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SPEAKER); break; + +#endif // GSOC_PEPPER + + case OB_EMPTY: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_EMPTY); break; + + } + } + else { + switch( GS(tselem->id->name)) { + case ID_SCE: + tselem_draw_icon_uibut(&arg, ICON_SCENE_DATA); break; + case ID_ME: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_MESH); break; + case ID_CU: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CURVE); break; + case ID_MB: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_META); break; + case ID_LT: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LATTICE); break; + case ID_LA: + { + Lamp *la= (Lamp *)tselem->id; + + switch(la->type) { + case LA_LOCAL: + tselem_draw_icon_uibut(&arg, ICON_LAMP_POINT); break; + case LA_SUN: + tselem_draw_icon_uibut(&arg, ICON_LAMP_SUN); break; + case LA_SPOT: + tselem_draw_icon_uibut(&arg, ICON_LAMP_SPOT); break; + case LA_HEMI: + tselem_draw_icon_uibut(&arg, ICON_LAMP_HEMI); break; + case LA_AREA: + tselem_draw_icon_uibut(&arg, ICON_LAMP_AREA); break; + default: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LAMP); break; + } + break; + } + case ID_MA: + tselem_draw_icon_uibut(&arg, ICON_MATERIAL_DATA); break; + case ID_TE: + tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break; + case ID_IM: + tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break; + +#if 0 // GSOC_PEPPER + + case ID_SPK: + case ID_SO: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_SPEAKER); break; + +#endif // GSOC_PEPPER + + case ID_AR: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_ARMATURE); break; + case ID_CA: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CAMERA); break; + case ID_KE: + tselem_draw_icon_uibut(&arg, ICON_SHAPEKEY_DATA); break; + case ID_WO: + tselem_draw_icon_uibut(&arg, ICON_WORLD_DATA); break; + case ID_AC: + tselem_draw_icon_uibut(&arg, ICON_ACTION); break; + case ID_NLA: + tselem_draw_icon_uibut(&arg, ICON_NLA); break; + case ID_TXT: + tselem_draw_icon_uibut(&arg, ICON_SCRIPT); break; + case ID_GR: + tselem_draw_icon_uibut(&arg, ICON_GROUP); break; + case ID_LI: + tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break; + } + } +} + +static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int xmax, int *offsx, int ys) +{ + TreeElement *te; + TreeStoreElem *tselem; + int active; + + for(te= lb->first; te; te= te->next) { + + /* exit drawing early */ + if((*offsx) - UI_UNIT_X > xmax) + break; + + tselem= TREESTORE(te); + + /* object hierarchy always, further constrained on level */ + if(level<1 || (tselem->type==0 && te->idcode==ID_OB)) { + + /* active blocks get white circle */ + if(tselem->type==0) { + if(te->idcode==ID_OB) active= (OBACT==(Object *)tselem->id); + else if(scene->obedit && scene->obedit->data==tselem->id) active= 1; // XXX use context? + else active= tree_element_active(C, scene, soops, te, 0); + } + else active= tree_element_type_active(NULL, scene, soops, te, tselem, 0); + + if(active) { + float ufac= UI_UNIT_X/20.0f; + + uiSetRoundBox(15); + glColor4ub(255, 255, 255, 100); + uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); + glEnable(GL_BLEND); /* roundbox disables */ + } + + tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); + te->xs= (float)*offsx; + te->ys= (float)ys; + te->xend= (short)*offsx+UI_UNIT_X; + te->flag |= TE_ICONROW; // for click + + (*offsx) += UI_UNIT_X; + } + + /* this tree element always has same amount of branches, so dont draw */ + if(tselem->type!=TSE_R_LAYER) + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, level+1, xmax, offsx, ys); + } + +} + +/* closed tree element */ +static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) +{ + TreeElement *ten; + + /* store coord and continue, we need coordinates for elements outside view too */ + te->xs= (float)startx; + te->ys= (float)(*starty); + + for(ten= te->subtree.first; ten; ten= ten->next) { + outliner_set_coord_tree_element(soops, ten, startx+UI_UNIT_X, starty); + } +} + + +static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty) +{ + TreeElement *ten; + TreeStoreElem *tselem; + float ufac= UI_UNIT_X/20.0f; + int offsx= 0, active=0; // active=1 active obj, else active data + + tselem= TREESTORE(te); + + if(*starty+2*UI_UNIT_Y >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) { + int xmax= ar->v2d.cur.xmax; + + /* icons can be ui buts, we dont want it to overlap with restrict */ + if((soops->flag & SO_HIDE_RESTRICTCOLS)==0) + xmax-= OL_TOGW+UI_UNIT_X; + + glEnable(GL_BLEND); + + /* colors for active/selected data */ + if(tselem->type==0) { + if(te->idcode==ID_SCE) { + if(tselem->id == (ID *)scene) { + glColor4ub(255, 255, 255, 100); + active= 2; + } + } + else if(te->idcode==ID_GR) { + Group *gr = (Group *)tselem->id; + + if(group_select_flag(gr)) { + char col[4]; + UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); + col[3]= 100; + glColor4ubv((GLubyte *)col); + + active= 2; + } + } + else if(te->idcode==ID_OB) { + Object *ob= (Object *)tselem->id; + + if(ob==OBACT || (ob->flag & SELECT)) { + char col[4]= {0, 0, 0, 0}; + + /* outliner active ob: always white text, circle color now similar to view3d */ + + active= 2; /* means it draws a color circle */ + if(ob==OBACT) { + if(ob->flag & SELECT) { + UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col); + col[3]= 100; + } + + active= 1; /* means it draws white text */ + } + else if(ob->flag & SELECT) { + UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); + col[3]= 100; + } + + glColor4ubv((GLubyte *)col); + } + + } + else if(scene->obedit && scene->obedit->data==tselem->id) { + glColor4ub(255, 255, 255, 100); + active= 2; + } + else { + if(tree_element_active(C, scene, soops, te, 0)) { + glColor4ub(220, 220, 255, 100); + active= 2; + } + } + } + else { + if( tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active= 2; + glColor4ub(220, 220, 255, 100); + } + + /* active circle */ + if(active) { + uiSetRoundBox(15); + uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); + glEnable(GL_BLEND); /* roundbox disables it */ + + te->flag |= TE_ACTIVE; // for lookup in display hierarchies + } + + /* open/close icon, only when sublevels, except for scene */ + if(te->subtree.first || (tselem->type==0 && te->idcode==ID_SCE) || (te->flag & TE_LAZY_CLOSED)) { + int icon_x; + if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) + icon_x = startx; + else + icon_x = startx+5*ufac; + + // icons a bit higher + if(tselem->flag & TSE_CLOSED) + UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT); + else + UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN); + } + offsx+= UI_UNIT_X; + + /* datatype icon */ + + if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { + // icons a bit higher + tselem_draw_icon(block, xmax, (float)startx+offsx - 0.5f*ufac, (float)*starty+2.0f*ufac, tselem, te, 1.0f); + + offsx+= UI_UNIT_X; + } + else + offsx+= 2*ufac; + + if(tselem->type==0 && tselem->id->lib) { + glPixelTransferf(GL_ALPHA_SCALE, 0.5f); + if(tselem->id->flag & LIB_INDIRECT) + UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_INDIRECT); + else + UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_DIRECT); + glPixelTransferf(GL_ALPHA_SCALE, 1.0f); + offsx+= UI_UNIT_X; + } + glDisable(GL_BLEND); + + /* name */ + if(active==1) UI_ThemeColor(TH_TEXT_HI); + else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f); + else UI_ThemeColor(TH_TEXT); + + UI_DrawString(startx+offsx, *starty+5*ufac, te->name); + + offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name)); + + /* closed item, we draw the icons, not when it's a scene, or master-server list though */ + if(tselem->flag & TSE_CLOSED) { + if(te->subtree.first) { + if(tselem->type==0 && te->idcode==ID_SCE); + else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */ + int tempx= startx+offsx; + + // divider + UI_ThemeColorShade(TH_BACK, -40); + glRecti(tempx -10, *starty+4, tempx -8, *starty+UI_UNIT_Y-4); + + glEnable(GL_BLEND); + glPixelTransferf(GL_ALPHA_SCALE, 0.5); + + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty+2); + + glPixelTransferf(GL_ALPHA_SCALE, 1.0); + glDisable(GL_BLEND); + } + } + } + } + /* store coord and continue, we need coordinates for elements outside view too */ + te->xs= (float)startx; + te->ys= (float)*starty; + te->xend= startx+offsx; + + if((tselem->flag & TSE_CLOSED)==0) { + *starty-= UI_UNIT_Y; + + for(ten= te->subtree.first; ten; ten= ten->next) + outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+UI_UNIT_X, starty); + } + else { + for(ten= te->subtree.first; ten; ten= ten->next) + outliner_set_coord_tree_element(soops, te, startx, starty); + + *starty-= UI_UNIT_Y; + } +} + +static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, int *starty) +{ + TreeElement *te; + TreeStoreElem *tselem; + int y1, y2; + + if(lb->first==NULL) return; + + y1=y2= *starty; /* for vertical lines between objects */ + for(te=lb->first; te; te= te->next) { + y2= *starty; + tselem= TREESTORE(te); + + /* horizontal line? */ + if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE)) + glRecti(startx, *starty, startx+UI_UNIT_X, *starty-1); + + *starty-= UI_UNIT_Y; + + if((tselem->flag & TSE_CLOSED)==0) + outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty); + } + + /* vertical line */ + te= lb->last; + if(te->parent || lb->first!=lb->last) { + tselem= TREESTORE(te); + if(tselem->type==0 && te->idcode==ID_OB) { + + glRecti(startx, y1+UI_UNIT_Y, startx+1, y2); + } + } +} + +static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + + /* selection status */ + if((tselem->flag & TSE_CLOSED)==0) + if(tselem->type == TSE_RNA_STRUCT) + glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1); + + *starty-= UI_UNIT_Y; + if((tselem->flag & TSE_CLOSED)==0) { + outliner_draw_struct_marks(ar, soops, &te->subtree, starty); + if(tselem->type == TSE_RNA_STRUCT) + fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y); + } + } +} + +static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + + /* selection status */ + if(tselem->flag & TSE_SELECTED) { + glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); + } + *starty-= UI_UNIT_Y; + if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty); + } +} + + +static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops) +{ + TreeElement *te; + int starty, startx; + float col[4]; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once + + if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { + /* struct marks */ + UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); + //UI_ThemeColorShade(TH_BACK, -20); + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; + outliner_draw_struct_marks(ar, soops, &soops->tree, &starty); + } + + /* always draw selection fill before hierarchy */ + UI_GetThemeColor3fv(TH_BACK, col); + glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; + outliner_draw_selection(ar, soops, &soops->tree, &starty); + + // grey hierarchy lines + UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.4f); + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y/2-OL_Y_OFFSET; + startx= 6; + outliner_draw_hierarchy(soops, &soops->tree, startx, &starty); + + // items themselves + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; + startx= 0; + for(te= soops->tree.first; te; te= te->next) { + outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty); + } +} + + +static void outliner_back(ARegion *ar) +{ + int ystart; + + UI_ThemeColorShade(TH_BACK, 6); + ystart= (int)ar->v2d.tot.ymax; + ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; + + while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { + glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+UI_UNIT_Y); + ystart-= 2*UI_UNIT_Y; + } +} + +static void outliner_draw_restrictcols(ARegion *ar) +{ + int ystart; + + /* background underneath */ + UI_ThemeColor(TH_BACK); + glRecti((int)ar->v2d.cur.xmax-OL_TOGW, (int)ar->v2d.cur.ymin-V2D_SCROLL_HEIGHT-1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (int)ar->v2d.cur.ymax); + + UI_ThemeColorShade(TH_BACK, 6); + ystart= (int)ar->v2d.tot.ymax; + ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; + + while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { + glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+UI_UNIT_Y); + ystart-= 2*UI_UNIT_Y; + } + + UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); + + /* view */ + fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, + ar->v2d.cur.ymax, + ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, + ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); + + /* render */ + fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, + ar->v2d.cur.ymax, + ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, + ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); + + /* render */ + fdrawline(ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, + ar->v2d.cur.ymax, + ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, + ar->v2d.cur.ymin - V2D_SCROLL_HEIGHT); +} + +/* ****************************************************** */ +/* Main Entrypoint - Draw contents of Outliner editor */ + +void draw_outliner(const bContext *C) +{ + Main *mainvar= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + View2D *v2d= &ar->v2d; + SpaceOops *soops= CTX_wm_space_outliner(C); + uiBlock *block; + int sizey= 0, sizex= 0, sizex_rna= 0; + + outliner_build_tree(mainvar, scene, soops); // always + + /* get extents of data */ + outliner_height(soops, &soops->tree, &sizey); + + if (ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP)) { + /* RNA has two columns: + * - column 1 is (max_width + OL_RNA_COL_SPACEX) or + * (OL_RNA_COL_X), whichever is wider... + * - column 2 is fixed at OL_RNA_COL_SIZEX + * + * (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100) + */ + + /* get actual width of column 1 */ + outliner_rna_width(soops, &soops->tree, &sizex_rna, 0); + sizex_rna= MAX2(OL_RNA_COLX, sizex_rna+OL_RNA_COL_SPACEX); + + /* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */ + if (soops->outlinevis == SO_KEYMAP) + sizex= sizex_rna + OL_RNA_COL_SIZEX*3 + 50; // XXX this is only really a quick hack to make this wide enough... + else + sizex= sizex_rna + OL_RNA_COL_SIZEX + 50; + } + else { + /* width must take into account restriction columns (if visible) so that entries will still be visible */ + //outliner_width(soops, &soops->tree, &sizex); + outliner_rna_width(soops, &soops->tree, &sizex, 0); // XXX should use outliner_width instead when te->xend will be set correctly... + + /* constant offset for restriction columns */ + // XXX this isn't that great yet... + if ((soops->flag & SO_HIDE_RESTRICTCOLS)==0) + sizex += OL_TOGW*3; + } + + /* tweak to display last line (when list bigger than window) */ + sizey += V2D_SCROLL_HEIGHT; + + /* adds vertical offset */ + sizey += OL_Y_OFFSET; + + /* update size of tot-rect (extents of data/viewable area) */ + UI_view2d_totRect_set(v2d, sizex, sizey); + + /* force display to pixel coords */ + v2d->flag |= (V2D_PIXELOFS_X|V2D_PIXELOFS_Y); + /* set matrix for 2d-view controls */ + UI_view2d_view_ortho(v2d); + + /* draw outliner stuff (background, hierachy lines and names) */ + outliner_back(ar); + block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS); + outliner_draw_tree((bContext *)C, block, scene, ar, soops); + + if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { + /* draw rna buttons */ + outliner_draw_rnacols(ar, sizex_rna); + outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree); + } + else if(soops->outlinevis == SO_KEYMAP) { + outliner_draw_keymapbuts(block, ar, soops, &soops->tree); + } + else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { + /* draw restriction columns */ + outliner_draw_restrictcols(ar); + outliner_draw_restrictbuts(block, scene, ar, soops, &soops->tree); + } + + /* draw edit buttons if nessecery */ + outliner_buttons(C, block, ar, soops, &soops->tree); + + uiEndBlock(C, block); + uiDrawBlock(C, block); + + /* clear flag that allows quick redraws */ + soops->storeflag &= ~SO_TREESTORE_REDRAW; +} diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c new file mode 100644 index 00000000000..15167a3ba2c --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -0,0 +1,1398 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_outliner/outliner_edit.c + * \ingroup spoutliner + */ + +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_world_types.h" +#include "DNA_sequence_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_base.h" + +#if defined WIN32 && !defined _LIBC +# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ +#else +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include <fnmatch.h> +#endif + + +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_modifier.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_sequencer.h" + +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "ED_keyframing.h" + +#include "outliner_intern.h" + +/* ************************************************************** */ +/* Unused Utilities */ +// XXX: where to place these? + +/* This is not used anywhere at the moment */ +#if 0 +/* return 1 when levels were opened */ +static int outliner_open_back(SpaceOops *soops, TreeElement *te) +{ + TreeStoreElem *tselem; + int retval= 0; + + for (te= te->parent; te; te= te->parent) { + tselem= TREESTORE(te); + if (tselem->flag & TSE_CLOSED) { + tselem->flag &= ~TSE_CLOSED; + retval= 1; + } + } + return retval; +} + +static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for (te= lb->first; te; te= te->next) { + /* check if this tree-element was the one we're seeking */ + if (te == teFind) { + *found= 1; + return; + } + + /* try to see if sub-tree contains it then */ + outliner_open_reveal(soops, &te->subtree, teFind, found); + if (*found) { + tselem= TREESTORE(te); + if (tselem->flag & TSE_CLOSED) + tselem->flag &= ~TSE_CLOSED; + return; + } + } +} +#endif + +/* ************************************************************** */ +/* Click Activated */ + +/* Toggle Open/Closed ------------------------------------------- */ + +static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, int all, const float mval[2]) +{ + + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { + TreeStoreElem *tselem= TREESTORE(te); + + /* all below close/open? */ + if(all) { + tselem->flag &= ~TSE_CLOSED; + outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); + } + else { + if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; + else tselem->flag |= TSE_CLOSED; + } + + return 1; + } + + for(te= te->subtree.first; te; te= te->next) { + if(do_outliner_item_openclose(C, soops, te, all, mval)) + return 1; + } + return 0; + +} + +/* event can enterkey, then it opens/closes */ +static int outliner_item_openclose(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te; + float fmval[2]; + int all= RNA_boolean_get(op->ptr, "all"); + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); + + for(te= soops->tree.first; te; te= te->next) { + if(do_outliner_item_openclose(C, soops, te, all, fmval)) + break; + } + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_item_openclose(wmOperatorType *ot) +{ + ot->name= "Open/Close Item"; + ot->idname= "OUTLINER_OT_item_openclose"; + ot->description= "Toggle whether item under cursor is enabled or closed"; + + ot->invoke= outliner_item_openclose; + + ot->poll= ED_operator_outliner_active; + + RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items."); +} + +/* Rename --------------------------------------------------- */ + +static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, TreeElement *te, const float mval[2]) +{ + ReportList *reports= CTX_wm_reports(C); // XXX + + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { + TreeStoreElem *tselem= TREESTORE(te); + + /* name and first icon */ + if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { + + /* can't rename rna datablocks entries */ + if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) + ; + else if(ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) + BKE_report(reports, RPT_WARNING, "Cannot edit builtin name"); + else if(ELEM3(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) + BKE_report(reports, RPT_WARNING, "Cannot edit sequence name"); + else if(tselem->id->lib) { + // XXX error_libdata(); + } + else if(te->idcode == ID_LI && te->parent) { + BKE_report(reports, RPT_WARNING, "Cannot edit the path of an indirectly linked library"); + } + else { + tselem->flag |= TSE_TEXTBUT; + ED_region_tag_redraw(ar); + } + } + return 1; + } + + for(te= te->subtree.first; te; te= te->next) { + if(do_outliner_item_rename(C, ar, soops, te, mval)) return 1; + } + return 0; +} + +static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); + + for(te= soops->tree.first; te; te= te->next) { + if(do_outliner_item_rename(C, ar, soops, te, fmval)) break; + } + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_item_rename(wmOperatorType *ot) +{ + ot->name= "Rename Item"; + ot->idname= "OUTLINER_OT_item_rename"; + ot->description= "Rename item under cursor"; + + ot->invoke= outliner_item_rename; + + ot->poll= ED_operator_outliner_active; +} + +/* ************************************************************** */ +/* Setting Toggling Operators */ + +/* =============================================== */ +/* Toggling Utilities (Exported) */ + +/* Apply Settings ------------------------------- */ + +static int outliner_count_levels(SpaceOops *soops, ListBase *lb, int curlevel) +{ + TreeElement *te; + int level=curlevel, lev; + + for(te= lb->first; te; te= te->next) { + + lev= outliner_count_levels(soops, &te->subtree, curlevel+1); + if(lev>level) level= lev; + } + return level; +} + +int outliner_has_one_flag(SpaceOops *soops, ListBase *lb, short flag, short curlevel) +{ + TreeElement *te; + TreeStoreElem *tselem; + int level; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & flag) return curlevel; + + level= outliner_has_one_flag(soops, &te->subtree, flag, curlevel+1); + if(level) return level; + } + return 0; +} + +void outliner_set_flag(SpaceOops *soops, ListBase *lb, short flag, short set) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(set==0) tselem->flag &= ~flag; + else tselem->flag |= flag; + outliner_set_flag(soops, &te->subtree, flag, set); + } +} + +/* Restriction Columns ------------------------------- */ + +/* same check needed for both object operation and restrict column button func + * return 0 when in edit mode (cannot restrict view or select) + * otherwise return 1 */ +int common_restrict_check(bContext *C, Object *ob) +{ + /* Don't allow hide an object in edit mode, + * check the bug #22153 and #21609, #23977 + */ + Object *obedit= CTX_data_edit_object(C); + if (obedit && obedit == ob) { + /* found object is hidden, reset */ + if (ob->restrictflag & OB_RESTRICT_VIEW) + ob->restrictflag &= ~OB_RESTRICT_VIEW; + /* found object is unselectable, reset */ + if (ob->restrictflag & OB_RESTRICT_SELECT) + ob->restrictflag &= ~OB_RESTRICT_SELECT; + return 0; + } + + return 1; +} + +/* =============================================== */ +/* Restriction toggles */ + +/* Toggle Visibility ---------------------------------------- */ + +void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + Object *ob = (Object *)tselem->id; + + /* add check for edit mode */ + if(!common_restrict_check(C, ob)) return; + + if(base || (base= object_in_scene(ob, scene))) { + if((base->object->restrictflag ^= OB_RESTRICT_VIEW)) { + ED_base_object_select(base, BA_DESELECT); + } + } +} + +static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_VISIBLE, scene); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_visibility_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Visibility"; + ot->idname= "OUTLINER_OT_visibility_toggle"; + ot->description= "Toggle the visibility of selected items"; + + /* callbacks */ + ot->exec= outliner_toggle_visibility_exec; + ot->poll= ED_operator_outliner_active_no_editobject; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* Toggle Selectability ---------------------------------------- */ + +void object_toggle_selectability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + + if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); + if(base) { + base->object->restrictflag^=OB_RESTRICT_SELECT; + } +} + +static int outliner_toggle_selectability_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_selectability_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Selectability"; + ot->idname= "OUTLINER_OT_selectability_toggle"; + ot->description= "Toggle the selectability"; + + /* callbacks */ + ot->exec= outliner_toggle_selectability_exec; + ot->poll= ED_operator_outliner_active_no_editobject; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* Toggle Renderability ---------------------------------------- */ + +void object_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + + if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); + if(base) { + base->object->restrictflag^=OB_RESTRICT_RENDER; + } +} + +static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_renderability_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Renderability"; + ot->idname= "OUTLINER_OT_renderability_toggle"; + ot->description= "Toggle the renderability of selected items"; + + /* callbacks */ + ot->exec= outliner_toggle_renderability_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* =============================================== */ +/* Outliner setting toggles */ + +/* Toggle Expanded (Outliner) ---------------------------------------- */ + +static int outliner_toggle_expanded_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + + if (outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1)) + outliner_set_flag(soops, &soops->tree, TSE_CLOSED, 0); + else + outliner_set_flag(soops, &soops->tree, TSE_CLOSED, 1); + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_expanded_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Expand/Collapse All"; + ot->idname= "OUTLINER_OT_expanded_toggle"; + ot->description= "Expand/Collapse all items"; + + /* callbacks */ + ot->exec= outliner_toggle_expanded_exec; + ot->poll= ED_operator_outliner_active; + + /* no undo or registry, UI option */ +} + +/* Toggle Selected (Outliner) ---------------------------------------- */ + +static int outliner_toggle_selected_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + + if (outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1)) + outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); + else + outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 1); + + soops->storeflag |= SO_TREESTORE_REDRAW; + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_selected_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Selected"; + ot->idname= "OUTLINER_OT_selected_toggle"; + ot->description= "Toggle the Outliner selection of items"; + + /* callbacks */ + ot->exec= outliner_toggle_selected_exec; + ot->poll= ED_operator_outliner_active; + + /* no undo or registry, UI option */ +} + +/* ************************************************************** */ +/* Hotkey Only Operators */ + +/* Show Active --------------------------------------------------- */ + +static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *so= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + View2D *v2d= &ar->v2d; + + TreeElement *te; + int xdelta, ytop; + + // TODO: make this get this info from context instead... + if (OBACT == NULL) + return OPERATOR_CANCELLED; + + te= outliner_find_id(so, &so->tree, (ID *)OBACT); + if (te) { + /* make te->ys center of view */ + ytop= (int)(te->ys + (v2d->mask.ymax - v2d->mask.ymin)/2); + if (ytop>0) ytop= 0; + + v2d->cur.ymax= (float)ytop; + v2d->cur.ymin= (float)(ytop-(v2d->mask.ymax - v2d->mask.ymin)); + + /* make te->xs ==> te->xend center of view */ + xdelta = (int)(te->xs - v2d->cur.xmin); + v2d->cur.xmin += xdelta; + v2d->cur.xmax += xdelta; + + so->storeflag |= SO_TREESTORE_REDRAW; + } + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_show_active(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show Active"; + ot->idname= "OUTLINER_OT_show_active"; + ot->description= "Adjust the view so that the active Object is shown centered"; + + /* callbacks */ + ot->exec= outliner_show_active_exec; + ot->poll= ED_operator_outliner_active; +} + +/* View Panning --------------------------------------------------- */ + +static int outliner_scroll_page_exec(bContext *C, wmOperator *op) +{ + ARegion *ar= CTX_wm_region(C); + int dy= ar->v2d.mask.ymax - ar->v2d.mask.ymin; + int up= 0; + + if(RNA_boolean_get(op->ptr, "up")) + up= 1; + + if(up == 0) dy= -dy; + ar->v2d.cur.ymin+= dy; + ar->v2d.cur.ymax+= dy; + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_scroll_page(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Scroll Page"; + ot->idname= "OUTLINER_OT_scroll_page"; + ot->description= "Scroll page up or down"; + + /* callbacks */ + ot->exec= outliner_scroll_page_exec; + ot->poll= ED_operator_outliner_active; + + /* properties */ + RNA_def_boolean(ot->srna, "up", 0, "Up", "Scroll up one page."); +} + +/* Search ------------------------------------------------------- */ +// TODO: probably obsolete now with filtering? + +#if 0 + +/* recursive helper for function below */ +static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) +{ + TreeStoreElem *tselem= TREESTORE(te); + + /* store coord and continue, we need coordinates for elements outside view too */ + te->xs= (float)startx; + te->ys= (float)(*starty); + *starty-= UI_UNIT_Y; + + if((tselem->flag & TSE_CLOSED)==0) { + TreeElement *ten; + for(ten= te->subtree.first; ten; ten= ten->next) { + outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty); + } + } + +} + +/* to retrieve coordinates with redrawing the entire tree */ +static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops) +{ + TreeElement *te; + int starty= (int)(ar->v2d.tot.ymax)-UI_UNIT_Y; + int startx= 0; + + for(te= soops->tree.first; te; te= te->next) { + outliner_set_coordinates_element(soops, te, startx, &starty); + } +} + +/* find next element that has this name */ +static TreeElement *outliner_find_named(SpaceOops *soops, ListBase *lb, char *name, int flags, TreeElement *prev, int *prevFound) +{ + TreeElement *te, *tes; + + for (te= lb->first; te; te= te->next) { + int found = outliner_filter_has_name(te, name, flags); + + if(found) { + /* name is right, but is element the previous one? */ + if (prev) { + if ((te != prev) && (*prevFound)) + return te; + if (te == prev) { + *prevFound = 1; + } + } + else + return te; + } + + tes= outliner_find_named(soops, &te->subtree, name, flags, prev, prevFound); + if(tes) return tes; + } + + /* nothing valid found */ + return NULL; +} + +static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *soops, int again, int flags) +{ + ReportList *reports = NULL; // CTX_wm_reports(C); + TreeElement *te= NULL; + TreeElement *last_find; + TreeStoreElem *tselem; + int ytop, xdelta, prevFound=0; + char name[32]; + + /* get last found tree-element based on stored search_tse */ + last_find= outliner_find_tse(soops, &soops->search_tse); + + /* determine which type of search to do */ + if (again && last_find) { + /* no popup panel - previous + user wanted to search for next after previous */ + BLI_strncpy(name, soops->search_string, sizeof(name)); + flags= soops->search_flags; + + /* try to find matching element */ + te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound); + if (te==NULL) { + /* no more matches after previous, start from beginning again */ + prevFound= 1; + te= outliner_find_named(soops, &soops->tree, name, flags, last_find, &prevFound); + } + } + else { + /* pop up panel - no previous, or user didn't want search after previous */ + strcpy(name, ""); +// XXX if (sbutton(name, 0, sizeof(name)-1, "Find: ") && name[0]) { +// te= outliner_find_named(soops, &soops->tree, name, flags, NULL, &prevFound); +// } +// else return; /* XXX RETURN! XXX */ + } + + /* do selection and reveal */ + if (te) { + tselem= TREESTORE(te); + if (tselem) { + /* expand branches so that it will be visible, we need to get correct coordinates */ + if( outliner_open_back(soops, te)) + outliner_set_coordinates(ar, soops); + + /* deselect all visible, and select found element */ + outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); + tselem->flag |= TSE_SELECTED; + + /* make te->ys center of view */ + ytop= (int)(te->ys + (ar->v2d.mask.ymax-ar->v2d.mask.ymin)/2); + if(ytop>0) ytop= 0; + ar->v2d.cur.ymax= (float)ytop; + ar->v2d.cur.ymin= (float)(ytop-(ar->v2d.mask.ymax-ar->v2d.mask.ymin)); + + /* make te->xs ==> te->xend center of view */ + xdelta = (int)(te->xs - ar->v2d.cur.xmin); + ar->v2d.cur.xmin += xdelta; + ar->v2d.cur.xmax += xdelta; + + /* store selection */ + soops->search_tse= *tselem; + + BLI_strncpy(soops->search_string, name, 33); + soops->search_flags= flags; + + /* redraw */ + soops->storeflag |= SO_TREESTORE_REDRAW; + } + } + else { + /* no tree-element found */ + BKE_report(reports, RPT_WARNING, "Not found: %s", name); + } +} +#endif + +/* Show One Level ----------------------------------------------- */ + +/* helper function for Show/Hide one level operator */ +static void outliner_openclose_level(SpaceOops *soops, ListBase *lb, int curlevel, int level, int open) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + + if(open) { + if(curlevel<=level) tselem->flag &= ~TSE_CLOSED; + } + else { + if(curlevel>=level) tselem->flag |= TSE_CLOSED; + } + + outliner_openclose_level(soops, &te->subtree, curlevel+1, level, open); + } +} + +static int outliner_one_level_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + int add= RNA_boolean_get(op->ptr, "open"); + int level; + + level= outliner_has_one_flag(soops, &soops->tree, TSE_CLOSED, 1); + if(add==1) { + if(level) outliner_openclose_level(soops, &soops->tree, 1, level, 1); + } + else { + if(level==0) level= outliner_count_levels(soops, &soops->tree, 0); + if(level) outliner_openclose_level(soops, &soops->tree, 1, level-1, 0); + } + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_show_one_level(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show/Hide One Level"; + ot->idname= "OUTLINER_OT_show_one_level"; + ot->description= "Expand/collapse all entries by one level"; + + /* callbacks */ + ot->exec= outliner_one_level_exec; + ot->poll= ED_operator_outliner_active; + + /* no undo or registry, UI option */ + + /* properties */ + RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep."); +} + +/* Show Hierarchy ----------------------------------------------- */ + +/* helper function for tree_element_shwo_hierarchy() - recursively checks whether subtrees have any objects*/ +static int subtree_has_objects(SpaceOops *soops, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->type==0 && te->idcode==ID_OB) return 1; + if( subtree_has_objects(soops, &te->subtree)) return 1; + } + return 0; +} + +/* recursive helper function for Show Hierarchy operator */ +static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + + /* open all object elems, close others */ + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + + if(tselem->type==0) { + if(te->idcode==ID_SCE) { + if(tselem->id!=(ID *)scene) tselem->flag |= TSE_CLOSED; + else tselem->flag &= ~TSE_CLOSED; + } + else if(te->idcode==ID_OB) { + if(subtree_has_objects(soops, &te->subtree)) tselem->flag &= ~TSE_CLOSED; + else tselem->flag |= TSE_CLOSED; + } + } + else tselem->flag |= TSE_CLOSED; + + if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree); + } +} + +/* show entire object level hierarchy */ +static int outliner_show_hierarchy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + + /* recursively open/close levels */ + tree_element_show_hierarchy(scene, soops, &soops->tree); + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_show_hierarchy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show Hierarchy"; + ot->idname= "OUTLINER_OT_show_hierarchy"; + ot->description= "Open all object entries and close all others"; + + /* callbacks */ + ot->exec= outliner_show_hierarchy_exec; + ot->poll= ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views... + + /* no undo or registry, UI option */ +} + +/* ************************************************************** */ +/* ANIMATO OPERATIONS */ +/* KeyingSet and Driver Creation - Helper functions */ + +/* specialised poll callback for these operators to work in Datablocks view only */ +static int ed_operator_outliner_datablocks_active(bContext *C) +{ + ScrArea *sa= CTX_wm_area(C); + if ((sa) && (sa->spacetype==SPACE_OUTLINER)) { + SpaceOops *so= CTX_wm_space_outliner(C); + return (so->outlinevis == SO_DATABLOCKS); + } + return 0; +} + + +/* Helper func to extract an RNA path from selected tree element + * NOTE: the caller must zero-out all values of the pointers that it passes here first, as + * this function does not do that yet + */ +static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, + ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode)) +{ + ListBase hierarchy = {NULL, NULL}; + LinkData *ld; + TreeElement *tem, *temnext, *temsub; + TreeStoreElem *tse, *tsenext; + PointerRNA *ptr, *nextptr; + PropertyRNA *prop; + char *newpath=NULL; + + /* optimise tricks: + * - Don't do anything if the selected item is a 'struct', but arrays are allowed + */ + if (tselem->type == TSE_RNA_STRUCT) + return; + + /* Overview of Algorithm: + * 1. Go up the chain of parents until we find the 'root', taking note of the + * levels encountered in reverse-order (i.e. items are added to the start of the list + * for more convenient looping later) + * 2. Walk down the chain, adding from the first ID encountered + * (which will become the 'ID' for the KeyingSet Path), and build a + * path as we step through the chain + */ + + /* step 1: flatten out hierarchy of parents into a flat chain */ + for (tem= te->parent; tem; tem= tem->parent) { + ld= MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()"); + ld->data= tem; + BLI_addhead(&hierarchy, ld); + } + + /* step 2: step down hierarchy building the path (NOTE: addhead in previous loop was needed so that we can loop like this) */ + for (ld= hierarchy.first; ld; ld= ld->next) { + /* get data */ + tem= (TreeElement *)ld->data; + tse= TREESTORE(tem); + ptr= &tem->rnaptr; + prop= tem->directdata; + + /* check if we're looking for first ID, or appending to path */ + if (*id) { + /* just 'append' property to path + * - to prevent memory leaks, we must write to newpath not path, then free old path + swap them + */ + if(tse->type == TSE_RNA_PROPERTY) { + if(RNA_property_type(prop) == PROP_POINTER) { + /* for pointer we just append property name */ + newpath= RNA_path_append(*path, ptr, prop, 0, NULL); + } + else if(RNA_property_type(prop) == PROP_COLLECTION) { + char buf[128], *name; + + temnext= (TreeElement*)(ld->next->data); + tsenext= TREESTORE(temnext); + + nextptr= &temnext->rnaptr; + name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf)); + + if(name) { + /* if possible, use name as a key in the path */ + newpath= RNA_path_append(*path, NULL, prop, 0, name); + + if(name != buf) + MEM_freeN(name); + } + else { + /* otherwise use index */ + int index= 0; + + for(temsub=tem->subtree.first; temsub; temsub=temsub->next, index++) + if(temsub == temnext) + break; + + newpath= RNA_path_append(*path, NULL, prop, index, NULL); + } + + ld= ld->next; + } + } + + if(newpath) { + if (*path) MEM_freeN(*path); + *path= newpath; + newpath= NULL; + } + } + else { + /* no ID, so check if entry is RNA-struct, and if that RNA-struct is an ID datablock to extract info from */ + if (tse->type == TSE_RNA_STRUCT) { + /* ptr->data not ptr->id.data seems to be the one we want, since ptr->data is sometimes the owner of this ID? */ + if(RNA_struct_is_ID(ptr->type)) { + *id= (ID *)ptr->data; + + /* clear path */ + if(*path) { + MEM_freeN(*path); + path= NULL; + } + } + } + } + } + + /* step 3: if we've got an ID, add the current item to the path */ + if (*id) { + /* add the active property to the path */ + ptr= &te->rnaptr; + prop= te->directdata; + + /* array checks */ + if (tselem->type == TSE_RNA_ARRAY_ELEM) { + /* item is part of an array, so must set the array_index */ + *array_index= te->index; + } + else if (RNA_property_array_length(ptr, prop)) { + /* entire array was selected, so keyframe all */ + *flag |= KSP_FLAG_WHOLE_ARRAY; + } + + /* path */ + newpath= RNA_path_append(*path, NULL, prop, 0, NULL); + if (*path) MEM_freeN(*path); + *path= newpath; + } + + /* free temp data */ + BLI_freelistN(&hierarchy); +} + +/* =============================================== */ +/* Driver Operations */ + +/* These operators are only available in databrowser mode for now, as + * they depend on having RNA paths and/or hierarchies available. + */ +enum { + DRIVERS_EDITMODE_ADD = 0, + DRIVERS_EDITMODE_REMOVE, +} /*eDrivers_EditModes*/; + +/* Utilities ---------------------------------- */ + +/* Recursively iterate over tree, finding and working on selected items */ +static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportList *reports, short mode) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for (te= tree->first; te; te=te->next) { + tselem= TREESTORE(te); + + /* if item is selected, perform operation */ + if (tselem->flag & TSE_SELECTED) { + ID *id= NULL; + char *path= NULL; + int array_index= 0; + short flag= 0; + short groupmode= KSP_GROUP_KSNAME; + + /* check if RNA-property described by this selected element is an animateable prop */ + if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) { + /* get id + path + index info from the selected element */ + tree_element_to_path(soops, te, tselem, + &id, &path, &array_index, &flag, &groupmode); + } + + /* only if ID and path were set, should we perform any actions */ + if (id && path) { + short dflags = CREATEDRIVER_WITH_DEFAULT_DVAR; + int arraylen = 1; + + /* array checks */ + if (flag & KSP_FLAG_WHOLE_ARRAY) { + /* entire array was selected, so add drivers for all */ + arraylen= RNA_property_array_length(&te->rnaptr, te->directdata); + } + else + arraylen= array_index; + + /* we should do at least one step */ + if (arraylen == array_index) + arraylen++; + + /* for each array element we should affect, add driver */ + for (; array_index < arraylen; array_index++) { + /* action depends on mode */ + switch (mode) { + case DRIVERS_EDITMODE_ADD: + { + /* add a new driver with the information obtained (only if valid) */ + ANIM_add_driver(reports, id, path, array_index, dflags, DRIVER_TYPE_PYTHON); + } + break; + case DRIVERS_EDITMODE_REMOVE: + { + /* remove driver matching the information obtained (only if valid) */ + ANIM_remove_driver(reports, id, path, array_index, dflags); + } + break; + } + } + + /* free path, since it had to be generated */ + MEM_freeN(path); + } + + + } + + /* go over sub-tree */ + if ((tselem->flag & TSE_CLOSED)==0) + do_outliner_drivers_editop(soops, &te->subtree, reports, mode); + } +} + +/* Add Operator ---------------------------------- */ + +static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soutliner= CTX_wm_space_outliner(C); + + /* check for invalid states */ + if (soutliner == NULL) + return OPERATOR_CANCELLED; + + /* recursively go into tree, adding selected items */ + do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_ADD); + + /* send notifiers */ + WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot) +{ + /* api callbacks */ + ot->idname= "OUTLINER_OT_drivers_add_selected"; + ot->name= "Add Drivers for Selected"; + ot->description= "Add drivers to selected items"; + + /* api callbacks */ + ot->exec= outliner_drivers_addsel_exec; + ot->poll= ed_operator_outliner_datablocks_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + + +/* Remove Operator ---------------------------------- */ + +static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soutliner= CTX_wm_space_outliner(C); + + /* check for invalid states */ + if (soutliner == NULL) + return OPERATOR_CANCELLED; + + /* recursively go into tree, adding selected items */ + do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE); + + /* send notifiers */ + WM_event_add_notifier(C, ND_KEYS, NULL); // XXX + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->idname= "OUTLINER_OT_drivers_delete_selected"; + ot->name= "Delete Drivers for Selected"; + ot->description= "Delete drivers assigned to selected items"; + + /* api callbacks */ + ot->exec= outliner_drivers_deletesel_exec; + ot->poll= ed_operator_outliner_datablocks_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* =============================================== */ +/* Keying Set Operations */ + +/* These operators are only available in databrowser mode for now, as + * they depend on having RNA paths and/or hierarchies available. + */ +enum { + KEYINGSET_EDITMODE_ADD = 0, + KEYINGSET_EDITMODE_REMOVE, +} /*eKeyingSet_EditModes*/; + +/* Utilities ---------------------------------- */ + +/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */ +// TODO: should this be an API func? +static KeyingSet *verify_active_keyingset(Scene *scene, short add) +{ + KeyingSet *ks= NULL; + + /* sanity check */ + if (scene == NULL) + return NULL; + + /* try to find one from scene */ + if (scene->active_keyingset > 0) + ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); + + /* add if none found */ + // XXX the default settings have yet to evolve + if ((add) && (ks==NULL)) { + ks= BKE_keyingset_add(&scene->keyingsets, NULL, KEYINGSET_ABSOLUTE, 0); + scene->active_keyingset= BLI_countlist(&scene->keyingsets); + } + + return ks; +} + +/* Recursively iterate over tree, finding and working on selected items */ +static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for (te= tree->first; te; te=te->next) { + tselem= TREESTORE(te); + + /* if item is selected, perform operation */ + if (tselem->flag & TSE_SELECTED) { + ID *id= NULL; + char *path= NULL; + int array_index= 0; + short flag= 0; + short groupmode= KSP_GROUP_KSNAME; + + /* check if RNA-property described by this selected element is an animateable prop */ + if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) { + /* get id + path + index info from the selected element */ + tree_element_to_path(soops, te, tselem, + &id, &path, &array_index, &flag, &groupmode); + } + + /* only if ID and path were set, should we perform any actions */ + if (id && path) { + /* action depends on mode */ + switch (mode) { + case KEYINGSET_EDITMODE_ADD: + { + /* add a new path with the information obtained (only if valid) */ + // TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name + BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode); + ks->active_path= BLI_countlist(&ks->paths); + } + break; + case KEYINGSET_EDITMODE_REMOVE: + { + /* find the relevant path, then remove it from the KeyingSet */ + KS_Path *ksp= BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode); + + if (ksp) { + /* free path's data */ + BKE_keyingset_free_path(ks, ksp); + + ks->active_path= 0; + } + } + break; + } + + /* free path, since it had to be generated */ + MEM_freeN(path); + } + } + + /* go over sub-tree */ + if ((tselem->flag & TSE_CLOSED)==0) + do_outliner_keyingset_editop(soops, ks, &te->subtree, mode); + } +} + +/* Add Operator ---------------------------------- */ + +static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soutliner= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + KeyingSet *ks= verify_active_keyingset(scene, 1); + + /* check for invalid states */ + if (ks == NULL) { + BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set"); + return OPERATOR_CANCELLED; + } + if (soutliner == NULL) + return OPERATOR_CANCELLED; + + /* recursively go into tree, adding selected items */ + do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD); + + /* send notifiers */ + WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->idname= "OUTLINER_OT_keyingset_add_selected"; + ot->name= "Keying Set Add Selected"; + ot->description= "Add selected items (blue-grey rows) to active Keying Set"; + + /* api callbacks */ + ot->exec= outliner_keyingset_additems_exec; + ot->poll= ed_operator_outliner_datablocks_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + + +/* Remove Operator ---------------------------------- */ + +static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soutliner= CTX_wm_space_outliner(C); + Scene *scene= CTX_data_scene(C); + KeyingSet *ks= verify_active_keyingset(scene, 1); + + /* check for invalid states */ + if (soutliner == NULL) + return OPERATOR_CANCELLED; + + /* recursively go into tree, adding selected items */ + do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE); + + /* send notifiers */ + WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->idname= "OUTLINER_OT_keyingset_remove_selected"; + ot->name= "Keying Set Remove Selected"; + ot->description = "Remove selected items (blue-grey rows) from active Keying Set"; + + /* api callbacks */ + ot->exec= outliner_keyingset_removeitems_exec; + ot->poll= ed_operator_outliner_datablocks_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index cbb26d79c4b..cf4ce9c06a8 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -44,6 +44,8 @@ struct TreeStoreElem; struct bContext; struct Scene; struct ARegion; +struct ID; +struct Object; typedef struct TreeElement { struct TreeElement *next, *prev, *parent; @@ -107,27 +109,62 @@ typedef struct TreeElement { /* button events */ #define OL_NAMEBUTTON 1 +/* get TreeStoreElem associated with a TreeElement + * < a: (TreeElement) tree element to find stored element for + */ +#define TREESTORE(a) ((a)?soops->treestore->data+(a)->store_index:NULL) -/* outliner_ops.c */ -void outliner_operatortypes(void); -void outliner_keymap(struct wmKeyConfig *keyconf); +/* size constants */ +#define OL_Y_OFFSET 2 -/* outliner_header.c */ -void outliner_header_buttons(const struct bContext *C, struct ARegion *ar); +#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X*3) +#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X*2) +#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X + +#define OL_TOGW OL_TOG_RESTRICT_VIEWX + +#define OL_RNA_COLX (UI_UNIT_X*15) +#define OL_RNA_COL_SIZEX (UI_UNIT_X*7.5f) +#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5f) + + +/* outliner_tree.c ----------------------------------------------- */ + +void outliner_free_tree(ListBase *lb); + +TreeElement *outliner_find_tse(struct SpaceOops *soops, TreeStoreElem *tse); +TreeElement *outliner_find_id(struct SpaceOops *soops, ListBase *lb, struct ID *id); +struct ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode); + +void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct SpaceOops *soops); + +/* outliner_draw.c ---------------------------------------------- */ -/* outliner.c */ -void outliner_free_tree(struct ListBase *lb); -void outliner_select(struct SpaceOops *soops, struct ListBase *lb, int *index, short *selecting); void draw_outliner(const struct bContext *C); +/* outliner_select.c -------------------------------------------- */ +int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set); +int tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, int set); + +/* outliner_edit.c ---------------------------------------------- */ + +void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb, + void (*operation_cb)(struct bContext *C, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *)); + +int common_restrict_check(struct bContext *C, struct Object *ob); + +int outliner_has_one_flag(struct SpaceOops *soops, ListBase *lb, short flag, short curlevel); +void outliner_set_flag(struct SpaceOops *soops, ListBase *lb, short flag, short set); + +void object_toggle_visibility_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem); +void object_toggle_selectability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem); +void object_toggle_renderability_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem); + +/* ...................................................... */ + void OUTLINER_OT_item_activate(struct wmOperatorType *ot); void OUTLINER_OT_item_openclose(struct wmOperatorType *ot); void OUTLINER_OT_item_rename(struct wmOperatorType *ot); -void OUTLINER_OT_operation(struct wmOperatorType *ot); -void OUTLINER_OT_object_operation(struct wmOperatorType *ot); -void OUTLINER_OT_group_operation(struct wmOperatorType *ot); -void OUTLINER_OT_id_operation(struct wmOperatorType *ot); -void OUTLINER_OT_data_operation(struct wmOperatorType *ot); void OUTLINER_OT_show_one_level(struct wmOperatorType *ot); void OUTLINER_OT_show_active(struct wmOperatorType *ot); @@ -148,5 +185,23 @@ void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot); void OUTLINER_OT_drivers_add_selected(struct wmOperatorType *ot); void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot); -#endif /* ED_OUTLINER_INTERN_H */ +/* outliner_tools.c ---------------------------------------------- */ +void OUTLINER_OT_operation(struct wmOperatorType *ot); +void OUTLINER_OT_object_operation(struct wmOperatorType *ot); +void OUTLINER_OT_group_operation(struct wmOperatorType *ot); +void OUTLINER_OT_id_operation(struct wmOperatorType *ot); +void OUTLINER_OT_data_operation(struct wmOperatorType *ot); +void OUTLINER_OT_animdata_operation(struct wmOperatorType *ot); +void OUTLINER_OT_action_set(struct wmOperatorType *ot); + +/* ---------------------------------------------------------------- */ + +/* outliner_ops.c */ +void outliner_operatortypes(void); +void outliner_keymap(struct wmKeyConfig *keyconf); + +/* outliner_header.c */ +void outliner_header_buttons(const struct bContext *C, struct ARegion *ar); + +#endif /* ED_OUTLINER_INTERN_H */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 8bd30235931..f3e2c352172 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -57,6 +57,13 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_group_operation); WM_operatortype_append(OUTLINER_OT_id_operation); WM_operatortype_append(OUTLINER_OT_data_operation); + WM_operatortype_append(OUTLINER_OT_animdata_operation); + +#if 0 // GSOC_PEPPER + + WM_operatortype_append(OUTLINER_OT_action_set); + +#endif // GSOC_PEPPER WM_operatortype_append(OUTLINER_OT_show_one_level); WM_operatortype_append(OUTLINER_OT_show_active); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c new file mode 100644 index 00000000000..46a9bde8267 --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -0,0 +1,875 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_outliner/outliner_select.c + * \ingroup spoutliner + */ + +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_world_types.h" +#include "DNA_sequence_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_base.h" + +#if defined WIN32 && !defined _LIBC +# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ +#else +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include <fnmatch.h> +#endif + + +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_modifier.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_sequencer.h" + +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "outliner_intern.h" + +/* ****************************************************** */ +/* Outliner Selection (grey-blue highlight for rows) */ + +static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selecting) +{ + TreeElement *te; + TreeStoreElem *tselem; + int change= 0; + + for (te= lb->first; te && *index >= 0; te=te->next, (*index)--) { + tselem= TREESTORE(te); + + /* if we've encountered the right item, set its 'Outliner' selection status */ + if (*index == 0) { + /* this should be the last one, so no need to do anything with index */ + if ((te->flag & TE_ICONROW)==0) { + /* -1 value means toggle testing for now... */ + if (*selecting == -1) { + if (tselem->flag & TSE_SELECTED) + *selecting= 0; + else + *selecting= 1; + } + + /* set selection */ + if (*selecting) + tselem->flag |= TSE_SELECTED; + else + tselem->flag &= ~TSE_SELECTED; + + change |= 1; + } + } + else if ((tselem->flag & TSE_CLOSED)==0) { + /* Only try selecting sub-elements if we haven't hit the right element yet + * + * Hack warning: + * Index must be reduced before supplying it to the sub-tree to try to do + * selection, however, we need to increment it again for the next loop to + * function correctly + */ + (*index)--; + change |= outliner_select(soops, &te->subtree, index, selecting); + (*index)++; + } + } + + return change; +} + +/* ****************************************************** */ +/* Outliner Element Selection/Activation on Click */ + +static int tree_element_active_renderlayer(bContext *C, TreeElement *te, TreeStoreElem *tselem, int set) +{ + Scene *sce; + + /* paranoia check */ + if(te->idcode!=ID_SCE) + return 0; + sce= (Scene *)tselem->id; + + if(set) { + sce->r.actlay= tselem->nr; + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, sce); + } + else { + return sce->r.actlay==tselem->nr; + } + return 0; +} + +static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + TreeStoreElem *tselem= TREESTORE(te); + Scene *sce; + Base *base; + Object *ob= NULL; + + /* if id is not object, we search back */ + if(te->idcode==ID_OB) ob= (Object *)tselem->id; + else { + ob= (Object *)outliner_search_back(soops, te, ID_OB); + if(ob==OBACT) return 0; + } + if(ob==NULL) return 0; + + sce= (Scene *)outliner_search_back(soops, te, ID_SCE); + if(sce && scene != sce) { + ED_screen_set_scene(C, sce); + } + + /* find associated base in current scene */ + base= object_in_scene(ob, scene); + + if(base) { + if(set==2) { + /* swap select */ + if(base->flag & SELECT) + ED_base_object_select(base, BA_DESELECT); + else + ED_base_object_select(base, BA_SELECT); + } + else { + /* deleselect all */ + scene_deselect_all(scene); + ED_base_object_select(base, BA_SELECT); + } + if(C) { + ED_base_object_activate(C, base); /* adds notifier */ + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } + } + + if(ob!=scene->obedit) + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); + + return 1; +} + +static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + TreeElement *tes; + Object *ob; + + /* we search for the object parent */ + ob= (Object *)outliner_search_back(soops, te, ID_OB); + // note: ob->matbits can be NULL when a local object points to a library mesh. + if(ob==NULL || ob!=OBACT || ob->matbits==NULL) return 0; // just paranoia + + /* searching in ob mat array? */ + tes= te->parent; + if(tes->idcode==ID_OB) { + if(set) { + ob->actcol= te->index+1; + ob->matbits[te->index]= 1; // make ob material active too + ob->colbits |= (1<<te->index); + } + else { + if(ob->actcol == te->index+1) + if(ob->matbits[te->index]) return 1; + } + } + /* or we search for obdata material */ + else { + if(set) { + ob->actcol= te->index+1; + ob->matbits[te->index]= 0; // make obdata material active too + ob->colbits &= ~(1<<te->index); + } + else { + if(ob->actcol == te->index+1) + if(ob->matbits[te->index]==0) return 1; + } + } + if(set) { + WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, NULL); + } + return 0; +} + +static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + TreeElement *tep; + TreeStoreElem /* *tselem,*/ *tselemp; + Object *ob=OBACT; + SpaceButs *sbuts=NULL; + + if(ob==NULL) return 0; // no active object + + /*tselem= TREESTORE(te);*/ /*UNUSED*/ + + /* find buttons area (note, this is undefined really still, needs recode in blender) */ + /* XXX removed finding sbuts */ + + /* where is texture linked to? */ + tep= te->parent; + tselemp= TREESTORE(tep); + + if(tep->idcode==ID_WO) { + World *wrld= (World *)tselemp->id; + + if(set) { + if(sbuts) { + // XXX sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c + // XXX sbuts->texfrom= 1; + } +// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture + wrld->texact= te->index; + } + else if(tselemp->id == (ID *)(scene->world)) { + if(wrld->texact==te->index) return 1; + } + } + else if(tep->idcode==ID_LA) { + Lamp *la= (Lamp *)tselemp->id; + if(set) { + if(sbuts) { + // XXX sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c + // XXX sbuts->texfrom= 2; + } +// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture + la->texact= te->index; + } + else { + if(tselemp->id == ob->data) { + if(la->texact==te->index) return 1; + } + } + } + else if(tep->idcode==ID_MA) { + Material *ma= (Material *)tselemp->id; + if(set) { + if(sbuts) { + //sbuts->tabo= TAB_SHADING_TEX; // hack from header_buttonswin.c + // XXX sbuts->texfrom= 0; + } +// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture + ma->texact= (char)te->index; + + /* also set active material */ + ob->actcol= tep->index+1; + } + else if(tep->flag & TE_ACTIVE) { // this is active material + if(ma->texact==te->index) return 1; + } + } + + if(set) + WM_event_add_notifier(C, NC_TEXTURE, NULL); + + return 0; +} + + +static int tree_element_active_lamp(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + Object *ob; + + /* we search for the object parent */ + ob= (Object *)outliner_search_back(soops, te, ID_OB); + if(ob==NULL || ob!=OBACT) return 0; // just paranoia + + if(set) { +// XXX extern_set_butspace(F5KEY, 0); + } + else return 1; + + return 0; +} + +static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + Object *ob= (Object *)outliner_search_back(soops, te, ID_OB); + + if(set) + return 0; + + return scene->camera == ob; +} + +static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + TreeElement *tep; + TreeStoreElem *tselem=NULL; + Scene *sce=NULL; + + tep= te->parent; + if(tep) { + tselem= TREESTORE(tep); + sce= (Scene *)tselem->id; + } + + if(set) { // make new scene active + if(sce && scene != sce) { + ED_screen_set_scene(C, sce); + } + } + + if(tep==NULL || tselem->id == (ID *)scene) { + if(set) { +// XXX extern_set_butspace(F8KEY, 0); + } + else { + return 1; + } + } + return 0; +} + +static int tree_element_active_defgroup(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) +{ + Object *ob; + + /* id in tselem is object */ + ob= (Object *)tselem->id; + if(set) { + ob->actdef= te->index+1; + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); + } + else { + if(ob==OBACT) + if(ob->actdef== te->index+1) return 1; + } + return 0; +} + +static int tree_element_active_posegroup(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) +{ + Object *ob= (Object *)tselem->id; + + if(set) { + if (ob->pose) { + ob->pose->active_group= te->index+1; + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + } + } + else { + if(ob==OBACT && ob->pose) { + if (ob->pose->active_group== te->index+1) return 1; + } + } + return 0; +} + +static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) +{ + Object *ob= (Object *)tselem->id; + bArmature *arm= ob->data; + bPoseChannel *pchan= te->directdata; + + if(set) { + if(!(pchan->bone->flag & BONE_HIDDEN_P)) { + + if(set==2) ED_pose_deselectall(ob, 2); // 2 = clear active tag + else ED_pose_deselectall(ob, 0); // 0 = deselect + + if(set==2 && (pchan->bone->flag & BONE_SELECTED)) { + pchan->bone->flag &= ~BONE_SELECTED; + } else { + pchan->bone->flag |= BONE_SELECTED; + arm->act_bone= pchan->bone; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, ob); + + } + } + else { + if(ob==OBACT && ob->pose) { + if (pchan->bone->flag & BONE_SELECTED) return 1; + } + } + return 0; +} + +static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set) +{ + bArmature *arm= (bArmature *)tselem->id; + Bone *bone= te->directdata; + + if(set) { + if(!(bone->flag & BONE_HIDDEN_P)) { + if(set==2) ED_pose_deselectall(OBACT, 2); // 2 is clear active tag + else ED_pose_deselectall(OBACT, 0); + + if(set==2 && (bone->flag & BONE_SELECTED)) { + bone->flag &= ~BONE_SELECTED; + } else { + bone->flag |= BONE_SELECTED; + arm->act_bone= bone; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, OBACT); + } + } + else { + Object *ob= OBACT; + + if(ob && ob->data==arm) { + if (bone->flag & BONE_SELECTED) return 1; + } + } + return 0; +} + + +/* ebones only draw in editmode armature */ +static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature *arm, EditBone *ebone, short sel) +{ + if(sel) { + ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL; + arm->act_edbone= ebone; + // flush to parent? + if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag |= BONE_TIPSEL; + } + else { + ebone->flag &= ~(BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL); + // flush to parent? + if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag &= ~BONE_TIPSEL; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, scene->obedit); +} +static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) +{ + bArmature *arm= scene->obedit->data; + EditBone *ebone= te->directdata; + + if(set==1) { + if(!(ebone->flag & BONE_HIDDEN_A)) { + ED_armature_deselect_all(scene->obedit, 0); // deselect + tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); + return 1; + } + } + else if (set==2) { + if(!(ebone->flag & BONE_HIDDEN_A)) { + if(!(ebone->flag & BONE_SELECTED)) { + tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE); + return 1; + } + else { + /* entirely selected, so de-select */ + tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE); + return 0; + } + } + } + else if (ebone->flag & BONE_SELECTED) { + return 1; + } + return 0; +} + +static int tree_element_active_modifier(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) +{ + if(set) { + Object *ob= (Object *)tselem->id; + + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + +// XXX extern_set_butspace(F9KEY, 0); + } + + return 0; +} + +static int tree_element_active_psys(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) +{ + if(set) { + Object *ob= (Object *)tselem->id; + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); + +// XXX extern_set_butspace(F7KEY, 0); + } + + return 0; +} + +static int tree_element_active_constraint(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) +{ + if(set) { + Object *ob= (Object *)tselem->id; + + WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); +// XXX extern_set_butspace(F7KEY, 0); + } + + return 0; +} + +static int tree_element_active_text(bContext *UNUSED(C), Scene *UNUSED(scene), SpaceOops *UNUSED(soops), TreeElement *UNUSED(te), int UNUSED(set)) +{ + // XXX removed + return 0; +} + +static int tree_element_active_pose(bContext *C, Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) +{ + Object *ob= (Object *)tselem->id; + Base *base= object_in_scene(ob, scene); + + if(set) { + if(scene->obedit) + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); + + if(ob->mode & OB_MODE_POSE) + ED_armature_exit_posemode(C, base); + else + ED_armature_enter_posemode(C, base); + } + else { + if(ob->mode & OB_MODE_POSE) return 1; + } + return 0; +} + +static int tree_element_active_sequence(TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) +{ + Sequence *seq= (Sequence*) te->directdata; + + if(set) { +// XXX select_single_seq(seq, 1); + } + else { + if(seq->flag & SELECT) + return(1); + } + return(0); +} + +static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) +{ + Sequence *seq, *p; + Editing *ed= seq_give_editing(scene, FALSE); + + seq= (Sequence*)te->directdata; + if(set==0) { + if(seq->flag & SELECT) + return(1); + return(0); + } + +// XXX select_single_seq(seq, 1); + p= ed->seqbasep->first; + while(p) { + if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + p= p->next; + continue; + } + +// if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) +// XXX select_single_seq(p, 0); + p= p->next; + } + return(0); +} + +static int tree_element_active_keymap_item(bContext *UNUSED(C), TreeElement *te, TreeStoreElem *UNUSED(tselem), int set) +{ + wmKeyMapItem *kmi= te->directdata; + + if(set==0) { + if(kmi->flag & KMI_INACTIVE) return 0; + return 1; + } + else { + kmi->flag ^= KMI_INACTIVE; + } + return 0; +} + +/* ---------------------------------------------- */ + +/* generic call for ID data check or make/check active in UI */ +int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +{ + + switch(te->idcode) { + /* Note: no ID_OB: objects are handled specially to allow multiple + selection. See do_outliner_item_activate. */ + case ID_MA: + return tree_element_active_material(C, scene, soops, te, set); + case ID_WO: + return tree_element_active_world(C, scene, soops, te, set); + case ID_LA: + return tree_element_active_lamp(C, scene, soops, te, set); + case ID_TE: + return tree_element_active_texture(C, scene, soops, te, set); + case ID_TXT: + return tree_element_active_text(C, scene, soops, te, set); + case ID_CA: + return tree_element_active_camera(C, scene, soops, te, set); + } + return 0; +} + +/* generic call for non-id data to make/check active in UI */ +/* Context can be NULL when set==0 */ +int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set) +{ + switch(tselem->type) { + case TSE_DEFGROUP: + return tree_element_active_defgroup(C, scene, te, tselem, set); + case TSE_BONE: + return tree_element_active_bone(C, scene, te, tselem, set); + case TSE_EBONE: + return tree_element_active_ebone(C, scene, te, tselem, set); + case TSE_MODIFIER: + return tree_element_active_modifier(C, te, tselem, set); + case TSE_LINKED_OB: + if(set) tree_element_set_active_object(C, scene, soops, te, set); + else if(tselem->id==(ID *)OBACT) return 1; + break; + case TSE_LINKED_PSYS: + return tree_element_active_psys(C, scene, te, tselem, set); + case TSE_POSE_BASE: + return tree_element_active_pose(C, scene, te, tselem, set); + case TSE_POSE_CHANNEL: + return tree_element_active_posechannel(C, scene, te, tselem, set); + case TSE_CONSTRAINT: + return tree_element_active_constraint(C, te, tselem, set); + case TSE_R_LAYER: + return tree_element_active_renderlayer(C, te, tselem, set); + case TSE_POSEGRP: + return tree_element_active_posegroup(C, scene, te, tselem, set); + case TSE_SEQUENCE: + return tree_element_active_sequence(te, tselem, set); + case TSE_SEQUENCE_DUP: + return tree_element_active_sequence_dup(scene, te, tselem, set); + case TSE_KEYMAP_ITEM: + return tree_element_active_keymap_item(C, te, tselem, set); + + } + return 0; +} + +/* ================================================ */ + +static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2]) +{ + + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { + TreeStoreElem *tselem= TREESTORE(te); + int openclose= 0; + + /* open close icon */ + if((te->flag & TE_ICONROW)==0) { // hidden icon, no open/close + if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X) + openclose= 1; + } + + if(openclose) { + /* all below close/open? */ + if(extend) { + tselem->flag &= ~TSE_CLOSED; + outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); + } + else { + if(tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; + else tselem->flag |= TSE_CLOSED; + + } + + return 1; + } + /* name and first icon */ + else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { + + /* always makes active object */ + if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP) + tree_element_set_active_object(C, scene, soops, te, 1 + (extend!=0 && tselem->type==0)); + + if(tselem->type==0) { // the lib blocks + /* editmode? */ + if(te->idcode==ID_SCE) { + if(scene!=(Scene *)tselem->id) { + ED_screen_set_scene(C, (Scene *)tselem->id); + } + } + else if(te->idcode==ID_GR) { + Group *gr= (Group *)tselem->id; + GroupObject *gob; + + if(extend) { + int sel= BA_SELECT; + for(gob= gr->gobject.first; gob; gob= gob->next) { + if(gob->ob->flag & SELECT) { + sel= BA_DESELECT; + break; + } + } + + for(gob= gr->gobject.first; gob; gob= gob->next) { + ED_base_object_select(object_in_scene(gob->ob, scene), sel); + } + } + else { + scene_deselect_all(scene); + + for(gob= gr->gobject.first; gob; gob= gob->next) { + if((gob->ob->flag & SELECT) == 0) + ED_base_object_select(object_in_scene(gob->ob, scene), BA_SELECT); + } + } + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } + else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { + WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); + } else { // rest of types + tree_element_active(C, scene, soops, te, 1); + } + + } + else tree_element_type_active(C, scene, soops, te, tselem, 1+(extend!=0)); + + return 1; + } + } + + for(te= te->subtree.first; te; te= te->next) { + if(do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1; + } + return 0; +} + +/* event can enterkey, then it opens/closes */ +static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event) +{ + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te; + float fmval[2]; + int extend= RNA_boolean_get(op->ptr, "extend"); + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); + + if(!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && fmval[0] > ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX) + return OPERATOR_CANCELLED; + + for(te= soops->tree.first; te; te= te->next) { + if(do_outliner_item_activate(C, scene, ar, soops, te, extend, fmval)) break; + } + + if(te) { + ED_undo_push(C, "Outliner click event"); + } + else { + short selecting= -1; + int row; + + /* get row number - 100 here is just a dummy value since we don't need the column */ + UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET, + fmval[0], fmval[1], NULL, &row); + + /* select relevant row */ + if(outliner_select(soops, &soops->tree, &row, &selecting)) { + + soops->storeflag |= SO_TREESTORE_REDRAW; + + /* no need for undo push here, only changing outliner data which is + * scene level - campbell */ + /* ED_undo_push(C, "Outliner selection event"); */ + } + } + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_item_activate(wmOperatorType *ot) +{ + ot->name= "Activate Item"; + ot->idname= "OUTLINER_OT_item_activate"; + ot->description= "Handle mouse clicks to activate/select items"; + + ot->invoke= outliner_item_activate; + + ot->poll= ED_operator_outliner_active; + + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection for activation."); +} + +/* ****************************************************** */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c new file mode 100644 index 00000000000..f5e1a67010e --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -0,0 +1,1217 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_outliner/outliner_tools.c + * \ingroup spoutliner + */ + +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_world_types.h" +#include "DNA_sequence_types.h" +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_base.h" + +#if defined WIN32 && !defined _LIBC +# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ +#else +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include <fnmatch.h> +#endif + + +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_modifier.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_sequencer.h" + +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "outliner_intern.h" + +/* ****************************************************** */ + +/* ************ SELECTION OPERATIONS ********* */ + +static void set_operation_types(SpaceOops *soops, ListBase *lb, + int *scenelevel, + int *objectlevel, + int *idlevel, + int *datalevel) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & TSE_SELECTED) { + if(tselem->type) { + if(*datalevel==0) + *datalevel= tselem->type; + else if(*datalevel!=tselem->type) + *datalevel= -1; + } + else { + int idcode= GS(tselem->id->name); + switch(idcode) { + case ID_SCE: + *scenelevel= 1; + break; + case ID_OB: + *objectlevel= 1; + break; + + case ID_ME: case ID_CU: case ID_MB: case ID_LT: + case ID_LA: case ID_AR: case ID_CA: /* case ID_SPK: */ /* GSOC_PEPPER */ + case ID_MA: case ID_TE: case ID_IP: case ID_IM: + case ID_SO: case ID_KE: case ID_WO: case ID_AC: + case ID_NLA: case ID_TXT: case ID_GR: + if(*idlevel==0) *idlevel= idcode; + else if(*idlevel!=idcode) *idlevel= -1; + break; + } + } + } + if((tselem->flag & TSE_CLOSED)==0) { + set_operation_types(soops, &te->subtree, + scenelevel, objectlevel, idlevel, datalevel); + } + } +} + +#if 0 // GSOC_PEPPER + +static void unlink_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem)) +{ + /* just set action to NULL */ + BKE_animdata_set_action(CTX_wm_reports(C), tsep->id, NULL); +} + +#endif // GSOC_PEPPER + +static void unlink_material_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem)) +{ + Material **matar=NULL; + int a, totcol=0; + + if( GS(tsep->id->name)==ID_OB) { + Object *ob= (Object *)tsep->id; + totcol= ob->totcol; + matar= ob->mat; + } + else if( GS(tsep->id->name)==ID_ME) { + Mesh *me= (Mesh *)tsep->id; + totcol= me->totcol; + matar= me->mat; + } + else if( GS(tsep->id->name)==ID_CU) { + Curve *cu= (Curve *)tsep->id; + totcol= cu->totcol; + matar= cu->mat; + } + else if( GS(tsep->id->name)==ID_MB) { + MetaBall *mb= (MetaBall *)tsep->id; + totcol= mb->totcol; + matar= mb->mat; + } + + for(a=0; a<totcol; a++) { + if(a==te->index && matar[a]) { + matar[a]->id.us--; + matar[a]= NULL; + } + } +} + +static void unlink_texture_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem)) +{ + MTex **mtex= NULL; + int a; + + if( GS(tsep->id->name)==ID_MA) { + Material *ma= (Material *)tsep->id; + mtex= ma->mtex; + } + else if( GS(tsep->id->name)==ID_LA) { + Lamp *la= (Lamp *)tsep->id; + mtex= la->mtex; + } + else if( GS(tsep->id->name)==ID_WO) { + World *wrld= (World *)tsep->id; + mtex= wrld->mtex; + } + else return; + + for(a=0; a<MAX_MTEX; a++) { + if(a==te->index && mtex[a]) { + if(mtex[a]->tex) { + mtex[a]->tex->id.us--; + mtex[a]->tex= NULL; + } + } + } +} + +static void unlink_group_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + Group *group= (Group *)tselem->id; + + if(tsep) { + if( GS(tsep->id->name)==ID_OB) { + Object *ob= (Object *)tsep->id; + ob->dup_group= NULL; + } + } + else { + unlink_group(group); + } +} + +static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, + void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te=lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & TSE_SELECTED) { + if(tselem->type==0) { + TreeStoreElem *tsep= TREESTORE(te->parent); + operation_cb(C, scene, te, tsep, tselem); + } + } + if((tselem->flag & TSE_CLOSED)==0) { + outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb); + } + } +} + +/* */ + +static void object_select_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + + if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); + if(base && ((base->object->restrictflag & OB_RESTRICT_VIEW)==0)) { + base->flag |= SELECT; + base->object->flag |= SELECT; + } +} + +static void object_deselect_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + + if(base==NULL) base= object_in_scene((Object *)tselem->id, scene); + if(base) { + base->flag &= ~SELECT; + base->object->flag &= ~SELECT; + } +} + +static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Base *base= (Base *)te->directdata; + + if(base==NULL) + base= object_in_scene((Object *)tselem->id, scene); + if(base) { + // check also library later + if(scene->obedit==base->object) + ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR|EM_DO_UNDO); + + ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); + te->directdata= NULL; + tselem->id= NULL; + } + +} + +static void id_local_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + if (tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) { + tselem->id->lib= NULL; + tselem->id->flag= LIB_LOCAL; + new_id(NULL, tselem->id, NULL); + } +} + +static void id_fake_user_set_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + ID *id = tselem->id; + + if ((id) && ((id->flag & LIB_FAKEUSER) == 0)) { + id->flag |= LIB_FAKEUSER; + id_us_plus(id); + } +} + +static void id_fake_user_clear_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + ID *id = tselem->id; + + if ((id) && (id->flag & LIB_FAKEUSER)) { + id->flag &= ~LIB_FAKEUSER; + id_us_min(id); + } +} + +#if 0 // GSOC_PEPPER + +static void singleuser_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + ID *id = tselem->id; + + if (id) { + IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id; + PointerRNA ptr = {{0}}; + PropertyRNA *prop; + + RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr); + prop = RNA_struct_find_property(&ptr, "action"); + + id_single_user(C, id, &ptr, prop); + } +} + +#endif + +static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Group *group= (Group *)tselem->id; + GroupObject *gob; + Base *base; + + for(gob=group->gobject.first; gob; gob=gob->next) { + base= object_in_scene(gob->ob, scene); + if (base) { + base->object->flag |= SELECT; + base->flag |= SELECT; + } else { + /* link to scene */ + base= MEM_callocN( sizeof(Base), "add_base"); + BLI_addhead(&scene->base, base); + base->lay= (1<<20)-1; /*v3d->lay;*/ /* would be nice to use the 3d layer but the include's not here */ + gob->ob->flag |= SELECT; + base->flag = gob->ob->flag; + base->object= gob->ob; + id_lib_extern((ID *)gob->ob); /* incase these are from a linked group */ + } + } +} + +void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, + void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te=lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & TSE_SELECTED) { + if(tselem->type==0 && te->idcode==ID_OB) { + // when objects selected in other scenes... dunno if that should be allowed + Scene *scene_owner= (Scene *)outliner_search_back(soops, te, ID_SCE); + if(scene_owner && scene_act != scene_owner) { + ED_screen_set_scene(C, scene_owner); + } + /* important to use 'scene_owner' not scene_act else deleting objects can crash. + * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the + * outliner isnt showing scenes: Visible Layer draw mode for eg. */ + operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem); + } + } + if((tselem->flag & TSE_CLOSED)==0) { + outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb); + } + } +} + +/* ******************************************** */ + +#if 0 // GSOC_PEPPER + +static void unlinkact_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem) +{ + /* just set action to NULL */ + BKE_animdata_set_action(NULL, tselem->id, NULL); +} + +#endif // GSOC_PEPPER + +static void cleardrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem) +{ + IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id; + + /* just free drivers - stored as a list of F-Curves */ + free_fcurves(&iat->adt->drivers); +} + +static void refreshdrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem) +{ + IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id; + FCurve *fcu; + + /* loop over drivers, performing refresh (i.e. check graph_buttons.c and rna_fcurve.c for details) */ + for (fcu = iat->adt->drivers.first; fcu; fcu= fcu->next) { + fcu->flag &= ~FCURVE_DISABLED; + + if (fcu->driver) + fcu->driver->flag &= ~DRIVER_FLAG_INVALID; + } +} + +/* --------------------------------- */ + +static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) +{ + bPoseChannel *pchan= (bPoseChannel *)te->directdata; + + if(event==1) + pchan->bone->flag |= BONE_SELECTED; + else if(event==2) + pchan->bone->flag &= ~BONE_SELECTED; + else if(event==3) { + pchan->bone->flag |= BONE_HIDDEN_P; + pchan->bone->flag &= ~BONE_SELECTED; + } + else if(event==4) + pchan->bone->flag &= ~BONE_HIDDEN_P; +} + +static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) +{ + Bone *bone= (Bone *)te->directdata; + + if(event==1) + bone->flag |= BONE_SELECTED; + else if(event==2) + bone->flag &= ~BONE_SELECTED; + else if(event==3) { + bone->flag |= BONE_HIDDEN_P; + bone->flag &= ~BONE_SELECTED; + } + else if(event==4) + bone->flag &= ~BONE_HIDDEN_P; +} + +static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem)) +{ + EditBone *ebone= (EditBone *)te->directdata; + + if(event==1) + ebone->flag |= BONE_SELECTED; + else if(event==2) + ebone->flag &= ~BONE_SELECTED; + else if(event==3) { + ebone->flag |= BONE_HIDDEN_A; + ebone->flag &= ~BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; + } + else if(event==4) + ebone->flag &= ~BONE_HIDDEN_A; +} + +static void sequence_cb(int event, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tselem)) +{ +// Sequence *seq= (Sequence*) te->directdata; + if(event==1) { +// XXX select_single_seq(seq, 1); + } +} + +static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb, + void (*operation_cb)(int, TreeElement *, TreeStoreElem *)) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te=lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->flag & TSE_SELECTED) { + if(tselem->type==type) { + operation_cb(event, te, tselem); + } + } + if((tselem->flag & TSE_CLOSED)==0) { + outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb); + } + } +} + +/* **************************************** */ + +static EnumPropertyItem prop_object_op_types[] = { + {1, "SELECT", 0, "Select", ""}, + {2, "DESELECT", 0, "Deselect", ""}, + {4, "DELETE", 0, "Delete", ""}, + {6, "TOGVIS", 0, "Toggle Visible", ""}, + {7, "TOGSEL", 0, "Toggle Selectable", ""}, + {8, "TOGREN", 0, "Toggle Renderable", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int outliner_object_operation_exec(bContext *C, wmOperator *op) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + int event; + const char *str= NULL; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + + event= RNA_enum_get(op->ptr, "type"); + + if(event==1) { + Scene *sce= scene; // to be able to delete, scenes are set... + outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb); + if(scene != sce) { + ED_screen_set_scene(C, sce); + } + + str= "Select Objects"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } + else if(event==2) { + outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb); + str= "Deselect Objects"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } + else if(event==4) { + outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb); + DAG_scene_sort(bmain, scene); + str= "Delete Objects"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); + } + else if(event==5) { /* disabled, see above enum (ton) */ + outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb); + str= "Localized Objects"; + } + else if(event==6) { + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); + str= "Toggle Visibility"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_VISIBLE, scene); + } + else if(event==7) { + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb); + str= "Toggle Selectability"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + } + else if(event==8) { + outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); + str= "Toggle Renderability"; + WM_event_add_notifier(C, NC_SCENE|ND_OB_RENDER, scene); + } + + ED_undo_push(C, str); + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_object_operation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Outliner Object Operation"; + ot->idname= "OUTLINER_OT_object_operation"; + ot->description= ""; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= outliner_object_operation_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= 0; + + ot->prop= RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", ""); +} + +/* **************************************** */ + +static EnumPropertyItem prop_group_op_types[] = { + {1, "UNLINK", 0, "Unlink", ""}, + {2, "LOCAL", 0, "Make Local", ""}, + {3, "LINK", 0, "Link Group Objects to Scene", ""}, + {4, "TOGVIS", 0, "Toggle Visible", ""}, + {5, "TOGSEL", 0, "Toggle Selectable", ""}, + {6, "TOGREN", 0, "Toggle Renderable", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int outliner_group_operation_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + int event; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + + event= RNA_enum_get(op->ptr, "type"); + + if(event==1) { + outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); + ED_undo_push(C, "Unlink group"); + } + else if(event==2) { + outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); + ED_undo_push(C, "Localized Data"); + } + else if(event==3) { + outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); + ED_undo_push(C, "Link Group Objects to Scene"); + } + + + WM_event_add_notifier(C, NC_GROUP, NULL); + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_group_operation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Outliner Group Operation"; + ot->idname= "OUTLINER_OT_group_operation"; + ot->description= ""; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= outliner_group_operation_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= 0; + + ot->prop= RNA_def_enum(ot->srna, "type", prop_group_op_types, 0, "Group Operation", ""); +} + +/* **************************************** */ + +typedef enum eOutlinerIdOpTypes { + OUTLINER_IDOP_INVALID = 0, + + OUTLINER_IDOP_UNLINK, + OUTLINER_IDOP_LOCAL, + OUTLINER_IDOP_SINGLE, + + OUTLINER_IDOP_FAKE_ADD, + OUTLINER_IDOP_FAKE_CLEAR +} eOutlinerIdOpTypes; + +// TODO: implement support for changing the ID-block used +static EnumPropertyItem prop_id_op_types[] = { + {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""}, + {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""}, + {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""}, + {OUTLINER_IDOP_FAKE_ADD, "ADD_FAKE", 0, "Add Fake User", "Ensure datablock gets saved even if it isn't in use (e.g. for motion and material libraries)"}, + {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int outliner_id_operation_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; + eOutlinerIdOpTypes event; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + + set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); + + event= RNA_enum_get(op->ptr, "type"); + + switch (event) { + case OUTLINER_IDOP_UNLINK: + { + /* unlink datablock from its parent */ + switch (idlevel) { + +#if 0 // GSOC_PEPPER + + case ID_AC: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_action_cb); + + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL); + ED_undo_push(C, "Unlink action"); + break; + +#endif // GSOC_PEPPER + + case ID_MA: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_material_cb); + + WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL); + ED_undo_push(C, "Unlink material"); + break; + case ID_TE: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_texture_cb); + + WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL); + ED_undo_push(C, "Unlink texture"); + break; + default: + BKE_report(op->reports, RPT_WARNING, "Not Yet"); + break; + } + } + break; + + case OUTLINER_IDOP_LOCAL: + { + /* make local */ + outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); + ED_undo_push(C, "Localized Data"); + } + break; + +#if 0 // GSOC_PEPPER + + case OUTLINER_IDOP_SINGLE: + { + /* make single user */ + switch (idlevel) { + case ID_AC: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, singleuser_action_cb); + + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL); + ED_undo_push(C, "Single-User Action"); + break; + + default: + BKE_report(op->reports, RPT_WARNING, "Not Yet"); + break; + } + } + break; + +#endif // GSOC_PEPPER + + case OUTLINER_IDOP_FAKE_ADD: + { + /* set fake user */ + outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_fake_user_set_cb); + + WM_event_add_notifier(C, NC_ID|NA_EDITED, NULL); + ED_undo_push(C, "Add Fake User"); + } + break; + + case OUTLINER_IDOP_FAKE_CLEAR: + { + /* clear fake user */ + outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_fake_user_clear_cb); + + WM_event_add_notifier(C, NC_ID|NA_EDITED, NULL); + ED_undo_push(C, "Clear Fake User"); + } + break; + + default: + // invalid - unhandled + break; + } + + /* wrong notifier still... */ + WM_event_add_notifier(C, NC_ID|NA_EDITED, NULL); + + // XXX: this is just so that outliner is always up to date + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_OUTLINER, NULL); + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_id_operation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Outliner ID data Operation"; + ot->idname= "OUTLINER_OT_id_operation"; + ot->description= ""; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= outliner_id_operation_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= 0; + + ot->prop= RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID data Operation", ""); +} + +/* **************************************** */ + +static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *lb, ID *newid, + void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *)) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for (te=lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if (tselem->flag & TSE_SELECTED) { + if(tselem->type==type) { + TreeStoreElem *tsep = TREESTORE(te->parent); + operation_cb(te, tselem, tsep, newid); + } + } + if ((tselem->flag & TSE_CLOSED)==0) { + outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb); + } + } +} + +/* ------------------------------------------ */ + +#if 0 // GSOC_PEPPER + +static void actionset_id_cb(TreeElement *te, TreeStoreElem *tselem, TreeStoreElem *tsep, ID *actId) +{ + bAction *act = (bAction *)actId; + + if (tselem->type == TSE_ANIM_DATA) { + /* "animation" entries - action is child of this */ + BKE_animdata_set_action(NULL, tselem->id, act); + } + /* TODO: if any other "expander" channels which own actions need to support this menu, + * add: tselem->type = ... + */ + else if (tsep && (tsep->type == TSE_ANIM_DATA)) { + /* "animation" entries case again */ + BKE_animdata_set_action(NULL, tsep->id, act); + } + // TODO: other cases not supported yet +} + +static int outliner_action_set_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; + + bAction *act; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); + + /* get action to use */ + act= BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "action")); + + if (act == NULL) { + BKE_report(op->reports, RPT_ERROR, "No valid Action to add."); + return OPERATOR_CANCELLED; + } + else if (act->idroot == 0) { + /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ + BKE_reportf(op->reports, RPT_WARNING, + "Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems", + act->id.name+2); + } + + /* perform action if valid channel */ + if (datalevel == TSE_ANIM_DATA) + outliner_do_id_set_operation(soops, datalevel, &soops->tree, (ID*)act, actionset_id_cb); + else if (idlevel == ID_AC) + outliner_do_id_set_operation(soops, idlevel, &soops->tree, (ID*)act, actionset_id_cb); + else + return OPERATOR_CANCELLED; + + /* set notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL); + ED_undo_push(C, "Set action"); + + /* done */ + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_action_set(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Outliner Set Action"; + ot->idname= "OUTLINER_OT_action_set"; + ot->description= "Change the active action used"; + + /* api callbacks */ + ot->invoke= WM_enum_search_invoke; + ot->exec= outliner_action_set_exec; + ot->poll= ED_operator_outliner_active; + + /* flags */ + ot->flag= 0; + + /* props */ + // TODO: this would be nicer as an ID-pointer... + prop= RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", ""); + RNA_def_enum_funcs(prop, RNA_action_itemf); + ot->prop= prop; +} + +#endif // GSOC_PEPPER + +/* **************************************** */ + +typedef enum eOutliner_AnimDataOps { + OUTLINER_ANIMOP_INVALID = 0, + + OUTLINER_ANIMOP_SET_ACT, + OUTLINER_ANIMOP_CLEAR_ACT, + + OUTLINER_ANIMOP_REFRESH_DRV, + OUTLINER_ANIMOP_CLEAR_DRV + + //OUTLINER_ANIMOP_COPY_DRIVERS, + //OUTLINER_ANIMOP_PASTE_DRIVERS +} eOutliner_AnimDataOps; + +static EnumPropertyItem prop_animdata_op_types[] = { + {OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""}, + {OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""}, + {OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", ""}, + //{OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""}, + //{OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", ""}, + {OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int outliner_animdata_operation_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; + eOutliner_AnimDataOps event; + short updateDeps = 0; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + + event= RNA_enum_get(op->ptr, "type"); + set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); + + if (datalevel != TSE_ANIM_DATA) + return OPERATOR_CANCELLED; + + /* perform the core operation */ + switch (event) { + +#if 0 // GSOC_PEPPER + + case OUTLINER_ANIMOP_SET_ACT: + /* delegate once again... */ + WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL); + break; + + case OUTLINER_ANIMOP_CLEAR_ACT: + /* clear active action - using standard rules */ + outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb); + + WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL); + ED_undo_push(C, "Unlink action"); + break; + +#endif // GSOC_PEPPER + + case OUTLINER_ANIMOP_REFRESH_DRV: + outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb); + + WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN, NULL); + //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */ + updateDeps = 1; + break; + + case OUTLINER_ANIMOP_CLEAR_DRV: + outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb); + + WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN, NULL); + ED_undo_push(C, "Clear Drivers"); + updateDeps = 1; + break; + + default: // invalid + break; + } + + /* update dependencies */ + if (updateDeps) { + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + + /* rebuild depsgraph for the new deps */ + DAG_scene_sort(bmain, scene); + + /* force an update of depsgraph */ + DAG_ids_flush_update(bmain, 0); + } + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_animdata_operation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Outliner Animation Data Operation"; + ot->idname= "OUTLINER_OT_animdata_operation"; + ot->description= ""; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= outliner_animdata_operation_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= 0; + + ot->prop= RNA_def_enum(ot->srna, "type", prop_animdata_op_types, 0, "Animation Operation", ""); +} + +/* **************************************** */ + +static EnumPropertyItem prop_data_op_types[] = { + {1, "SELECT", 0, "Select", ""}, + {2, "DESELECT", 0, "Deselect", ""}, + {3, "HIDE", 0, "Hide", ""}, + {4, "UNHIDE", 0, "Unhide", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int outliner_data_operation_exec(bContext *C, wmOperator *op) +{ + SpaceOops *soops= CTX_wm_space_outliner(C); + int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; + int event; + + /* check for invalid states */ + if (soops == NULL) + return OPERATOR_CANCELLED; + + event= RNA_enum_get(op->ptr, "type"); + set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); + + if(datalevel==TSE_POSE_CHANNEL) { + if(event>0) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + ED_undo_push(C, "PoseChannel operation"); + } + } + else if(datalevel==TSE_BONE) { + if(event>0) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + ED_undo_push(C, "Bone operation"); + } + } + else if(datalevel==TSE_EBONE) { + if(event>0) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb); + WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL); + ED_undo_push(C, "EditBone operation"); + } + } + else if(datalevel==TSE_SEQUENCE) { + if(event>0) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb); + } + } + + return OPERATOR_FINISHED; +} + + +void OUTLINER_OT_data_operation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Outliner Data Operation"; + ot->idname= "OUTLINER_OT_data_operation"; + ot->description= ""; + + /* callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= outliner_data_operation_exec; + ot->poll= ED_operator_outliner_active; + + ot->flag= 0; + + ot->prop= RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", ""); +} + + +/* ******************** */ + + +static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, wmEvent *event, const float mval[2]) +{ + ReportList *reports = CTX_wm_reports(C); // XXX... + + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { + int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; + TreeStoreElem *tselem= TREESTORE(te); + + /* select object that's clicked on and popup context menu */ + if (!(tselem->flag & TSE_SELECTED)) { + + if ( outliner_has_one_flag(soops, &soops->tree, TSE_SELECTED, 1) ) + outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0); + + tselem->flag |= TSE_SELECTED; + /* redraw, same as outliner_select function */ + soops->storeflag |= SO_TREESTORE_REDRAW; + ED_region_tag_redraw(ar); + } + + set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); + + if(scenelevel) { + //if(objectlevel || datalevel || idlevel) error("Mixed selection"); + //else pupmenu("Scene Operations%t|Delete"); + } + else if(objectlevel) { + WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } + else if(idlevel) { + if(idlevel==-1 || datalevel) BKE_report(reports, RPT_WARNING, "Mixed selection"); + else { + if (idlevel==ID_GR) + WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL); + else + WM_operator_name_call(C, "OUTLINER_OT_id_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } + } + else if(datalevel) { + if(datalevel==-1) BKE_report(reports, RPT_WARNING, "Mixed selection"); + else { + if (datalevel == TSE_ANIM_DATA) + WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); + else if (datalevel == TSE_DRIVER_BASE) + /* do nothing... no special ops needed yet */; + else + WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } + } + + return 1; + } + + for(te= te->subtree.first; te; te= te->next) { + if(do_outliner_operation_event(C, scene, ar, soops, te, event, mval)) + return 1; + } + return 0; +} + + +static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + Scene *scene= CTX_data_scene(C); + ARegion *ar= CTX_wm_region(C); + SpaceOops *soops= CTX_wm_space_outliner(C); + TreeElement *te; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval+1); + + for(te= soops->tree.first; te; te= te->next) { + if(do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break; + } + + return OPERATOR_FINISHED; +} + +/* Menu only! Calls other operators */ +void OUTLINER_OT_operation(wmOperatorType *ot) +{ + ot->name= "Execute Operation"; + ot->idname= "OUTLINER_OT_operation"; + ot->description= "Context menu for item operations"; + + ot->invoke= outliner_operation; + + ot->poll= ED_operator_outliner_active; +} + +/* ****************************************************** */ diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c new file mode 100644 index 00000000000..3560bfb9896 --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -0,0 +1,1585 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_outliner/outliner_tree.c + * \ingroup spoutliner + */ + +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" +#include "DNA_world_types.h" +#include "DNA_sequence_types.h" + +#if 0 // GSOC_PEPPER + +#include "DNA_speaker_types.h" + +#endif // GSOC_PEPPER + +#include "DNA_object_types.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_base.h" + +#if defined WIN32 && !defined _LIBC +# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ +#else +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include <fnmatch.h> +#endif + + +#include "BKE_animsys.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_modifier.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_sequencer.h" + +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "outliner_intern.h" + +/* ********************************************************* */ +/* Defines */ + +#define TS_CHUNK 128 + +/* ********************************************************* */ +/* Persistant Data */ + +static void outliner_storage_cleanup(SpaceOops *soops) +{ + TreeStore *ts= soops->treestore; + + if(ts) { + TreeStoreElem *tselem; + int a, unused= 0; + + /* each element used once, for ID blocks with more users to have each a treestore */ + for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) tselem->used= 0; + + /* cleanup only after reading file or undo step, and always for + * RNA datablocks view in order to save memory */ + if(soops->storeflag & SO_TREESTORE_CLEANUP) { + + for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) { + if(tselem->id==NULL) unused++; + } + + if(unused) { + if(ts->usedelem == unused) { + MEM_freeN(ts->data); + ts->data= NULL; + ts->usedelem= ts->totelem= 0; + } + else { + TreeStoreElem *tsnewar, *tsnew; + + tsnew=tsnewar= MEM_mallocN((ts->usedelem-unused)*sizeof(TreeStoreElem), "new tselem"); + for(a=0, tselem= ts->data; a<ts->usedelem; a++, tselem++) { + if(tselem->id) { + *tsnew= *tselem; + tsnew++; + } + } + MEM_freeN(ts->data); + ts->data= tsnewar; + ts->usedelem-= unused; + ts->totelem= ts->usedelem; + } + } + } + } +} + +static void check_persistant(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) +{ + TreeStore *ts; + TreeStoreElem *tselem; + int a; + + /* case 1; no TreeStore */ + if(soops->treestore==NULL) { + soops->treestore= MEM_callocN(sizeof(TreeStore), "treestore"); + } + ts= soops->treestore; + + /* check if 'te' is in treestore */ + tselem= ts->data; + for(a=0; a<ts->usedelem; a++, tselem++) { + if(tselem->id==id && tselem->used==0) { + if((type==0 && tselem->type==0) ||(tselem->type==type && tselem->nr==nr)) { + te->store_index= a; + tselem->used= 1; + return; + } + } + } + + /* add 1 element to treestore */ + if(ts->usedelem==ts->totelem) { + TreeStoreElem *tsnew; + + tsnew= MEM_mallocN((ts->totelem+TS_CHUNK)*sizeof(TreeStoreElem), "treestore data"); + if(ts->data) { + memcpy(tsnew, ts->data, ts->totelem*sizeof(TreeStoreElem)); + MEM_freeN(ts->data); + } + ts->data= tsnew; + ts->totelem+= TS_CHUNK; + } + + tselem= ts->data+ts->usedelem; + + tselem->type= type; + if(type) tselem->nr= nr; // we're picky! :) + else tselem->nr= 0; + tselem->id= id; + tselem->used = 0; + tselem->flag= TSE_CLOSED; + te->store_index= ts->usedelem; + + ts->usedelem++; +} + +/* ********************************************************* */ +/* Tree Management */ + +void outliner_free_tree(ListBase *lb) +{ + while(lb->first) { + TreeElement *te= lb->first; + + outliner_free_tree(&te->subtree); + BLI_remlink(lb, te); + + if(te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name); + MEM_freeN(te); + } +} + +/* Find ith item from the treestore */ +TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) +{ + TreeElement *te= lb->first, *tes; + while(te) { + if(te->store_index==store_index) return te; + tes= outliner_find_tree_element(&te->subtree, store_index); + if(tes) return tes; + te= te->next; + } + return NULL; +} + +/* tse is not in the treestore, we use its contents to find a match */ +TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) +{ + TreeStore *ts= soops->treestore; + TreeStoreElem *tselem; + int a; + + if(tse->id==NULL) return NULL; + + /* check if 'tse' is in treestore */ + tselem= ts->data; + for(a=0; a<ts->usedelem; a++, tselem++) { + if((tse->type==0 && tselem->type==0) || (tselem->type==tse->type && tselem->nr==tse->nr)) { + if(tselem->id==tse->id) { + break; + } + } + } + if(tselem) + return outliner_find_tree_element(&soops->tree, a); + + return NULL; +} + +/* Find treestore that refers to given ID */ +TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) +{ + TreeElement *te, *tes; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(tselem->type==0) { + if(tselem->id==id) return te; + /* only deeper on scene or object */ + if( te->idcode==ID_OB || te->idcode==ID_SCE || (soops->outlinevis == SO_GROUPS && te->idcode==ID_GR)) { + tes= outliner_find_id(soops, &te->subtree, id); + if(tes) return tes; + } + } + } + return NULL; +} + + +ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode) +{ + TreeStoreElem *tselem; + te= te->parent; + + while(te) { + tselem= TREESTORE(te); + if(tselem->type==0 && te->idcode==idcode) return tselem->id; + te= te->parent; + } + return NULL; +} + + +/* ********************************************************* */ + +/* Prototype, see functions below */ +static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, + TreeElement *parent, short type, short index); + +/* -------------------------------------------------------- */ + +/* special handling of hierarchical non-lib data */ +static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curBone, + TreeElement *parent, int *a) +{ + TreeElement *te= outliner_add_element(soops, lb, id, parent, TSE_BONE, *a); + + (*a)++; + te->name= curBone->name; + te->directdata= curBone; + + for(curBone= curBone->childbase.first; curBone; curBone=curBone->next) { + outliner_add_bone(soops, &te->subtree, id, curBone, te, a); + } +} + +/* -------------------------------------------------------- */ + +#define LOG2I(x) (int)(log(x)/M_LN2) + +static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, SceneRenderLayer *srl) +{ + TreeStoreElem *tselem = NULL; + TreeElement *te = NULL; + + /* log stuff is to convert bitflags (powers of 2) to small integers, + * in order to not overflow short tselem->nr */ + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED)); + te->name= "Combined"; + te->directdata= &srl->passflag; + + /* save cpu cycles, but we add the first to invoke an open/close triangle */ + tselem = TREESTORE(tenla); + if(tselem->flag & TSE_CLOSED) + return; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z)); + te->name= "Z"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR)); + te->name= "Vector"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL)); + te->name= "Normal"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV)); + te->name= "UV"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST)); + te->name= "Mist"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB)); + te->name= "Index Object"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA)); + te->name= "Index Material"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA)); + te->name= "Color"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE)); + te->name= "Diffuse"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC)); + te->name= "Specular"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW)); + te->name= "Shadow"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO)); + te->name= "AO"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT)); + te->name= "Reflection"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT)); + te->name= "Refraction"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT)); + te->name= "Indirect"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT)); + te->name= "Environment"; + te->directdata= &srl->passflag; + + te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT)); + te->name= "Emit"; + te->directdata= &srl->passflag; +} + +#undef LOG2I + +static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *sce, TreeElement *te) +{ + SceneRenderLayer *srl; + TreeElement *tenla= outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0); + int a; + + tenla->name= "RenderLayers"; + for(a=0, srl= sce->r.layers.first; srl; srl= srl->next, a++) { + TreeElement *tenlay= outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a); + tenlay->name= srl->name; + tenlay->directdata= &srl->passflag; + + if(srl->light_override) + outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0); + if(srl->mat_override) + outliner_add_element(soops, &tenlay->subtree, srl->mat_override, tenlay, TSE_LINKED_MAT, 0); + + outliner_add_passes(soops, tenlay, &sce->id, srl); + } + + // TODO: move this to the front? + if (sce->adt) + outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); + + outliner_add_element(soops, lb, sce->world, te, 0, 0); +} + +// can be inlined if necessary +static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob) +{ + int a = 0; + + if (ob->adt) + outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0); + + outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this + + if (ob->proxy && ob->id.lib==NULL) + outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0); + + outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0); + + if (ob->pose) { + bArmature *arm= ob->data; + bPoseChannel *pchan; + TreeElement *ten; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0); + + tenla->name= "Pose"; + + /* channels undefined in editmode, but we want the 'tenla' pose icon itself */ + if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) { + int a= 0, const_index= 1000; /* ensure unique id for bone constraints */ + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) { + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); + ten->name= pchan->name; + ten->directdata= pchan; + pchan->prev= (bPoseChannel *)ten; + + if(pchan->constraints.first) { + //Object *target; + bConstraint *con; + TreeElement *ten1; + TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); + //char *str; + + tenla1->name= "Constraints"; + for(con= pchan->constraints.first; con; con= con->next, const_index++) { + ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index); +#if 0 /* disabled as it needs to be reworked for recoded constraints system */ + target= get_constraint_target(con, &str); + if(str && str[0]) ten1->name= str; + else if(target) ten1->name= target->id.name+2; + else ten1->name= con->name; +#endif + ten1->name= con->name; + ten1->directdata= con; + /* possible add all other types links? */ + } + } + } + /* make hierarchy */ + ten= tenla->subtree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + tselem= TREESTORE(ten); + if(tselem->type==TSE_POSE_CHANNEL) { + pchan= (bPoseChannel *)ten->directdata; + if(pchan->parent) { + BLI_remlink(&tenla->subtree, ten); + par= (TreeElement *)pchan->parent->prev; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } + } + ten= nten; + } + /* restore prev pointers */ + pchan= ob->pose->chanbase.first; + if(pchan) pchan->prev= NULL; + for(; pchan; pchan= pchan->next) { + if(pchan->next) pchan->next->prev= pchan; + } + } + + /* Pose Groups */ + if(ob->pose->agroups.first) { + bActionGroup *agrp; + TreeElement *ten; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0); + int a= 0; + + tenla->name= "Bone Groups"; + for (agrp=ob->pose->agroups.first; agrp; agrp=agrp->next, a++) { + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSEGRP, a); + ten->name= agrp->name; + ten->directdata= agrp; + } + } + } + + for(a=0; a<ob->totcol; a++) + outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a); + + if(ob->constraints.first) { + //Object *target; + bConstraint *con; + TreeElement *ten; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); + //char *str; + + tenla->name= "Constraints"; + for (con=ob->constraints.first, a=0; con; con= con->next, a++) { + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); +#if 0 /* disabled due to constraints system targets recode... code here needs review */ + target= get_constraint_target(con, &str); + if(str && str[0]) ten->name= str; + else if(target) ten->name= target->id.name+2; + else ten->name= con->name; +#endif + ten->name= con->name; + ten->directdata= con; + /* possible add all other types links? */ + } + } + + if (ob->modifiers.first) { + ModifierData *md; + TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); + int index; + + temod->name = "Modifiers"; + 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); + } + else if (md->type==eModifierType_Curve) { + outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_LINKED_OB, 0); + } + else if (md->type==eModifierType_Armature) { + outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_LINKED_OB, 0); + } + else if (md->type==eModifierType_Hook) { + outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_LINKED_OB, 0); + } + else if (md->type==eModifierType_ParticleSystem) { + TreeElement *ten; + ParticleSystem *psys= ((ParticleSystemModifierData*) md)->psys; + + ten = outliner_add_element(soops, &te->subtree, ob, te, TSE_LINKED_PSYS, 0); + ten->directdata = psys; + ten->name = psys->part->id.name+2; + } + } + } + + /* vertex groups */ + if (ob->defbase.first) { + bDeformGroup *defgroup; + TreeElement *ten; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0); + + tenla->name= "Vertex Groups"; + for (defgroup=ob->defbase.first, a=0; defgroup; defgroup=defgroup->next, a++) { + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a); + ten->name= defgroup->name; + ten->directdata= defgroup; + } + } + + /* duplicated group */ + if (ob->dup_group) + outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0); +} + +// can be inlined if necessary +static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, ID *id) +{ + /* tuck pointer back in object, to construct hierarchy */ + if (GS(id->name)==ID_OB) id->newid= (ID *)te; + + /* expand specific data always */ + switch (GS(id->name)) { + case ID_LI: + { + te->name= ((Library *)id)->name; + } + break; + case ID_SCE: + { + outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te); + } + break; + case ID_OB: + { + outliner_add_object_contents(soops, te, tselem, (Object *)id); + } + break; + case ID_ME: + { + Mesh *me= (Mesh *)id; + int a; + + if (me->adt) + outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0); + + outliner_add_element(soops, &te->subtree, me->key, te, 0, 0); + for(a=0; a<me->totcol; a++) + outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a); + /* could do tfaces with image links, but the images are not grouped nicely. + would require going over all tfaces, sort images in use. etc... */ + } + break; + case ID_CU: + { + Curve *cu= (Curve *)id; + int a; + + if (cu->adt) + outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0); + + for(a=0; a<cu->totcol; a++) + outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a); + } + break; + case ID_MB: + { + MetaBall *mb= (MetaBall *)id; + int a; + + if (mb->adt) + outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0); + + for(a=0; a<mb->totcol; a++) + outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a); + } + break; + case ID_MA: + { + Material *ma= (Material *)id; + int a; + + if (ma->adt) + outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0); + + for(a=0; a<MAX_MTEX; a++) { + if(ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); + } + } + break; + case ID_TE: + { + Tex *tex= (Tex *)id; + + if (tex->adt) + outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0); + + outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0); + } + break; + case ID_CA: + { + Camera *ca= (Camera *)id; + + if (ca->adt) + outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0); + } + break; + case ID_LA: + { + Lamp *la= (Lamp *)id; + int a; + + if (la->adt) + outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0); + + for(a=0; a<MAX_MTEX; a++) { + if(la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); + } + } + break; + +#if 0 // GSOC_PEPPER + + case ID_SPK: + { + Speaker *spk= (Speaker *)id; + + if(spk->adt) + outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0); + } + break; + +#endif // GSOC_PEPPER + + case ID_WO: + { + World *wrld= (World *)id; + int a; + + if (wrld->adt) + outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0); + + for(a=0; a<MAX_MTEX; a++) { + if(wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); + } + } + break; + case ID_KE: + { + Key *key= (Key *)id; + + if (key->adt) + outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0); + } + break; + case ID_AC: + { + // XXX do we want to be exposing the F-Curves here? + //bAction *act= (bAction *)id; + } + break; + case ID_AR: + { + bArmature *arm= (bArmature *)id; + int a= 0; + + if (arm->adt) + outliner_add_element(soops, &te->subtree, arm, te, TSE_ANIM_DATA, 0); + + if(arm->edbo) { + EditBone *ebone; + TreeElement *ten; + + for (ebone = arm->edbo->first; ebone; ebone=ebone->next, a++) { + ten= outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a); + ten->directdata= ebone; + ten->name= ebone->name; + ebone->temp= ten; + } + /* make hierarchy */ + ten= te->subtree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + ebone= (EditBone *)ten->directdata; + if(ebone->parent) { + BLI_remlink(&te->subtree, ten); + par= ebone->parent->temp; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } + ten= nten; + } + } + else { + /* do not extend Armature when we have posemode */ + tselem= TREESTORE(te->parent); + if( GS(tselem->id->name)==ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE); + else { + Bone *curBone; + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + outliner_add_bone(soops, &te->subtree, id, curBone, te, &a); + } + } + } + } + break; + } +} + +// TODO: this function needs to be split up! It's getting a bit too large... +static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, + TreeElement *parent, short type, short index) +{ + TreeElement *te; + TreeStoreElem *tselem; + ID *id= idv; + int a = 0; + + if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + id= ((PointerRNA*)idv)->id.data; + if(!id) id= ((PointerRNA*)idv)->data; + } + + if(id==NULL) return NULL; + + te= MEM_callocN(sizeof(TreeElement), "tree elem"); + /* add to the visual tree */ + BLI_addtail(lb, te); + /* add to the storage */ + check_persistant(soops, te, id, type, index); + tselem= TREESTORE(te); + + te->parent= parent; + te->index= index; // for data arays + if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)); + else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)); + else if(type==TSE_ANIM_DATA); + else { + te->name= id->name+2; // default, can be overridden by Library or non-ID data + te->idcode= GS(id->name); + } + + if(type==0) { + /* ID datablock */ + outliner_add_id_contents(soops, te, tselem, id); + } + else if(type==TSE_ANIM_DATA) { + IdAdtTemplate *iat = (IdAdtTemplate *)idv; + AnimData *adt= (AnimData *)iat->adt; + + /* this element's info */ + te->name= "Animation"; + te->directdata= adt; + + /* Action */ + outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0); + + /* Drivers */ + if (adt->drivers.first) { + TreeElement *ted= outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0); + ID *lastadded= NULL; + FCurve *fcu; + + ted->name= "Drivers"; + + for (fcu= adt->drivers.first; fcu; fcu= fcu->next) { + if (fcu->driver && fcu->driver->variables.first) { + ChannelDriver *driver= fcu->driver; + DriverVar *dvar; + + for (dvar= driver->variables.first; dvar; dvar= dvar->next) { + /* loop over all targets used here */ + DRIVER_TARGETS_USED_LOOPER(dvar) + { + if (lastadded != dtar->id) { + // XXX this lastadded check is rather lame, and also fails quite badly... + outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0); + lastadded= dtar->id; + } + } + DRIVER_TARGETS_LOOPER_END + } + } + } + } + + /* NLA Data */ + if (adt->nla_tracks.first) { + TreeElement *tenla= outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0); + NlaTrack *nlt; + int a= 0; + + tenla->name= "NLA Tracks"; + + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + TreeElement *tenlt= outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a); + NlaStrip *strip; + TreeElement *ten; + int b= 0; + + tenlt->name= nlt->name; + + for (strip=nlt->strips.first; strip; strip=strip->next, b++) { + ten= outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b); + if(ten) ten->directdata= strip; + } + } + } + } + else if(type==TSE_SEQUENCE) { + Sequence *seq= (Sequence*) idv; + Sequence *p; + + /* + * The idcode is a little hack, but the outliner + * only check te->idcode if te->type is equal to zero, + * so this is "safe". + */ + te->idcode= seq->type; + te->directdata= seq; + + if(seq->type<7) { + /* + * This work like the sequence. + * If the sequence have a name (not default name) + * show it, in other case put the filename. + */ + if(strcmp(seq->name, "SQ")) + te->name= seq->name; + else { + if((seq->strip) && (seq->strip->stripdata)) + te->name= seq->strip->stripdata->name; + else + te->name= "SQ None"; + } + + if(seq->type==SEQ_META) { + te->name= "Meta Strip"; + p= seq->seqbase.first; + while(p) { + outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); + p= p->next; + } + } + else + outliner_add_element(soops, &te->subtree, (void*)seq->strip, te, TSE_SEQ_STRIP, index); + } + else + te->name= "Effect"; + } + else if(type==TSE_SEQ_STRIP) { + Strip *strip= (Strip *)idv; + + if(strip->dir) + te->name= strip->dir; + else + te->name= "Strip None"; + te->directdata= strip; + } + else if(type==TSE_SEQUENCE_DUP) { + Sequence *seq= (Sequence*)idv; + + te->idcode= seq->type; + te->directdata= seq; + te->name= seq->strip->stripdata->name; + } + else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv; + PropertyRNA *prop, *iterprop; + PropertyType proptype; + int a, tot; + + /* we do lazy build, for speed and to avoid infinite recusion */ + + if(ptr->data == NULL) { + te->name= "(empty)"; + } + else if(type == TSE_RNA_STRUCT) { + /* struct */ + te->name= RNA_struct_name_get_alloc(ptr, NULL, 0); + + if(te->name) + te->flag |= TE_FREE_NAME; + else + te->name= (char*)RNA_struct_ui_name(ptr->type); + + iterprop= RNA_struct_iterator_property(ptr->type); + tot= RNA_property_collection_length(ptr, iterprop); + + /* auto open these cases */ + if(!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER) + if(!tselem->used) + tselem->flag &= ~TSE_CLOSED; + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; a<tot; a++) + outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a); + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + + te->rnaptr= *ptr; + } + else if(type == TSE_RNA_PROPERTY) { + /* property */ + iterprop= RNA_struct_iterator_property(ptr->type); + RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr); + + prop= propptr.data; + proptype= RNA_property_type(prop); + + te->name= (char*)RNA_property_ui_name(prop); + te->directdata= prop; + te->rnaptr= *ptr; + + if(proptype == PROP_POINTER) { + pptr= RNA_property_pointer_get(ptr, prop); + + if(pptr.data) { + if(!(tselem->flag & TSE_CLOSED)) + outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); + else + te->flag |= TE_LAZY_CLOSED; + } + } + else if(proptype == PROP_COLLECTION) { + tot= RNA_property_collection_length(ptr, prop); + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; a<tot; a++) { + RNA_property_collection_lookup_int(ptr, prop, a, &pptr); + outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, a); + } + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + } + else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { + tot= RNA_property_array_length(ptr, prop); + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; a<tot; a++) + outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a); + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + } + } + else if(type == TSE_RNA_ARRAY_ELEM) { + char c; + + prop= parent->directdata; + + te->directdata= prop; + te->rnaptr= *ptr; + te->index= index; + + c= RNA_property_array_item_char(prop, index); + + te->name= MEM_callocN(sizeof(char)*20, "OutlinerRNAArrayName"); + if(c) sprintf((char *)te->name, " %c", c); + else sprintf((char *)te->name, " %d", index+1); + te->flag |= TE_FREE_NAME; + } + } + else if(type == TSE_KEYMAP) { + wmKeyMap *km= (wmKeyMap *)idv; + wmKeyMapItem *kmi; + char opname[OP_MAX_TYPENAME]; + + te->directdata= idv; + te->name= km->idname; + + if(!(tselem->flag & TSE_CLOSED)) { + a= 0; + + for (kmi= km->items.first; kmi; kmi= kmi->next, a++) { + const char *key= WM_key_event_string(kmi->type); + + if(key[0]) { + wmOperatorType *ot= NULL; + + if(kmi->propvalue); + else ot= WM_operatortype_find(kmi->idname, 0); + + if(ot || kmi->propvalue) { + TreeElement *ten= outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); + + ten->directdata= kmi; + + if(kmi->propvalue) { + ten->name= "Modal map, not yet"; + } + else { + WM_operator_py_idname(opname, ot->idname); + ten->name= BLI_strdup(opname); + ten->flag |= TE_FREE_NAME; + } + } + } + } + } + else + te->flag |= TE_LAZY_CLOSED; + } + + return te; +} + +/* ======================================================= */ +/* Sequencer mode tree building */ + +/* Helped function to put duplicate sequence in the same tree. */ +static int need_add_seq_dup(Sequence *seq) +{ + Sequence *p; + + if((!seq->strip) || (!seq->strip->stripdata) || (!seq->strip->stripdata->name)) + return(1); + + /* + * First check backward, if we found a duplicate + * sequence before this, don't need it, just return. + */ + p= seq->prev; + while(p) { + if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + p= p->prev; + continue; + } + + if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) + return(2); + p= p->prev; + } + + p= seq->next; + while(p) { + if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + p= p->next; + continue; + } + + if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) + return(0); + p= p->next; + } + return(1); +} + +static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index) +{ + TreeElement *ch; + Sequence *p; + + p= seq; + while(p) { + if((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + p= p->next; + continue; + } + + if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) + ch= outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); + p= p->next; + } +} + +/* ======================================================= */ +/* Generic Tree Building helpers - order these are called is top to bottom */ + +/* Hierarchy --------------------------------------------- */ + +/* make sure elements are correctly nested */ +static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) +{ + TreeElement *te, *ten, *tep; + TreeStoreElem *tselem; + + /* build hierarchy */ + // XXX also, set extents here... + te= lb->first; + while(te) { + ten= te->next; + tselem= TREESTORE(te); + + if(tselem->type==0 && te->idcode==ID_OB) { + Object *ob= (Object *)tselem->id; + if(ob->parent && ob->parent->id.newid) { + BLI_remlink(lb, te); + tep= (TreeElement *)ob->parent->id.newid; + BLI_addtail(&tep->subtree, te); + // set correct parent pointers + for(te=tep->subtree.first; te; te= te->next) te->parent= tep; + } + } + te= ten; + } +} + +/* Sorting ------------------------------------------------------ */ + +typedef struct tTreeSort { + TreeElement *te; + ID *id; + const char *name; + short idcode; +} tTreeSort; + +/* alphabetical comparator */ +static int treesort_alpha(const void *v1, const void *v2) +{ + const tTreeSort *x1= v1, *x2= v2; + int comp; + + /* first put objects last (hierarchy) */ + comp= (x1->idcode==ID_OB); + if(x2->idcode==ID_OB) comp+=2; + + if(comp==1) return 1; + else if(comp==2) return -1; + else if(comp==3) { + comp= strcmp(x1->name, x2->name); + + if( comp>0 ) return 1; + else if( comp<0) return -1; + return 0; + } + return 0; +} + +/* this is nice option for later? doesnt look too useful... */ +#if 0 +static int treesort_obtype_alpha(const void *v1, const void *v2) +{ + const tTreeSort *x1= v1, *x2= v2; + + /* first put objects last (hierarchy) */ + if(x1->idcode==ID_OB && x2->idcode!=ID_OB) return 1; + else if(x2->idcode==ID_OB && x1->idcode!=ID_OB) return -1; + else { + /* 2nd we check ob type */ + if(x1->idcode==ID_OB && x2->idcode==ID_OB) { + if( ((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1; + else if( ((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1; + else return 0; + } + else { + int comp= strcmp(x1->name, x2->name); + + if( comp>0 ) return 1; + else if( comp<0) return -1; + return 0; + } + } +} +#endif + +/* sort happens on each subtree individual */ +static void outliner_sort(SpaceOops *soops, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + int totelem=0; + + te= lb->last; + if(te==NULL) return; + tselem= TREESTORE(te); + + /* sorting rules; only object lists or deformgroups */ + if( (tselem->type==TSE_DEFGROUP) || (tselem->type==0 && te->idcode==ID_OB)) { + + /* count first */ + for(te= lb->first; te; te= te->next) totelem++; + + if(totelem>1) { + tTreeSort *tear= MEM_mallocN(totelem*sizeof(tTreeSort), "tree sort array"); + tTreeSort *tp=tear; + int skip= 0; + + for(te= lb->first; te; te= te->next, tp++) { + tselem= TREESTORE(te); + tp->te= te; + tp->name= te->name; + tp->idcode= te->idcode; + if(tselem->type && tselem->type!=TSE_DEFGROUP) tp->idcode= 0; // dont sort this + tp->id= tselem->id; + } + /* keep beginning of list */ + for(tp= tear, skip=0; skip<totelem; skip++, tp++) + if(tp->idcode) break; + + if(skip<totelem) + qsort(tear+skip, totelem-skip, sizeof(tTreeSort), treesort_alpha); + + lb->first=lb->last= NULL; + tp= tear; + while(totelem--) { + BLI_addtail(lb, tp->te); + tp++; + } + MEM_freeN(tear); + } + } + + for(te= lb->first; te; te= te->next) { + outliner_sort(soops, &te->subtree); + } +} + +/* Filtering ----------------------------------------------- */ + +static int outliner_filter_has_name(TreeElement *te, const char *name, int flags) +{ +#if 0 + int found= 0; + + /* determine if match */ + if (flags & SO_FIND_CASE_SENSITIVE) { + if (flags & SO_FIND_COMPLETE) + found= strcmp(te->name, name) == 0; + else + found= strstr(te->name, name) != NULL; + } + else { + if (flags & SO_FIND_COMPLETE) + found= BLI_strcasecmp(te->name, name) == 0; + else + found= BLI_strcasestr(te->name, name) != NULL; + } +#else + + int fn_flag= 0; + int found= 0; + + if ((flags & SO_FIND_CASE_SENSITIVE) == 0) + fn_flag |= FNM_CASEFOLD; + + if (flags & SO_FIND_COMPLETE) { + found= fnmatch(name, te->name, fn_flag)==0; + } + else { + char fn_name[sizeof(((struct SpaceOops *)NULL)->search_string) + 2]; + sprintf(fn_name, "*%s*", name); + found= fnmatch(fn_name, te->name, fn_flag)==0; + } + return found; +#endif +} + +static int outliner_filter_tree(SpaceOops *soops, ListBase *lb) +{ + TreeElement *te, *ten; + TreeStoreElem *tselem; + + /* although we don't have any search string, we return TRUE + * since the entire tree is ok then... + */ + if (soops->search_string[0]==0) + return 1; + + for (te= lb->first; te; te= ten) { + ten= te->next; + + if (0==outliner_filter_has_name(te, soops->search_string, soops->search_flags)) { + /* item isn't something we're looking for, but... + * - if the subtree is expanded, check if there are any matches that can be easily found + * so that searching for "cu" in the default scene will still match the Cube + * - otherwise, we can't see within the subtree and the item doesn't match, + * so these can be safely ignored (i.e. the subtree can get freed) + */ + tselem= TREESTORE(te); + + if ((tselem->flag & TSE_CLOSED) || outliner_filter_tree(soops, &te->subtree)==0) { + outliner_free_tree(&te->subtree); + BLI_remlink(lb, te); + + if(te->flag & TE_FREE_NAME) MEM_freeN((void *)te->name); + MEM_freeN(te); + } + } + else { + /* filter subtree too */ + outliner_filter_tree(soops, &te->subtree); + } + } + + /* if there are still items in the list, that means that there were still some matches */ + return (lb->first != NULL); +} + +/* ======================================================= */ +/* Main Tree Building API */ + +/* Main entry point for building the tree data-structure that the outliner represents */ +// TODO: split each mode into its own function? +void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) +{ + Base *base; + Object *ob; + TreeElement *te=NULL, *ten; + TreeStoreElem *tselem; + int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */ + + if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW)) + return; + + outliner_free_tree(&soops->tree); + outliner_storage_cleanup(soops); + + /* clear ob id.new flags */ + for(ob= mainvar->object.first; ob; ob= ob->id.next) ob->id.newid= NULL; + + /* options */ + if(soops->outlinevis == SO_LIBRARIES) { + Library *lib; + + for(lib= mainvar->library.first; lib; lib= lib->id.next) { + ten= outliner_add_element(soops, &soops->tree, lib, NULL, 0, 0); + lib->id.newid= (ID *)ten; + } + /* make hierarchy */ + ten= soops->tree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + tselem= TREESTORE(ten); + lib= (Library *)tselem->id; + if(lib->parent) { + BLI_remlink(&soops->tree, ten); + par= (TreeElement *)lib->parent->id.newid; + BLI_addtail(&par->subtree, ten); + ten->parent= par; + } + ten= nten; + } + /* restore newid pointers */ + for(lib= mainvar->library.first; lib; lib= lib->id.next) + lib->id.newid= NULL; + + } + else if(soops->outlinevis == SO_ALL_SCENES) { + Scene *sce; + for(sce= mainvar->scene.first; sce; sce= sce->id.next) { + te= outliner_add_element(soops, &soops->tree, sce, NULL, 0, 0); + tselem= TREESTORE(te); + if(sce==scene && show_opened) + tselem->flag &= ~TSE_CLOSED; + + for(base= sce->base.first; base; base= base->next) { + ten= outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); + ten->directdata= base; + } + outliner_make_hierarchy(soops, &te->subtree); + /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ + for(base= sce->base.first; base; base= base->next) base->object->id.newid= NULL; + } + } + else if(soops->outlinevis == SO_CUR_SCENE) { + + outliner_add_scene_contents(soops, &soops->tree, scene, NULL); + + for(base= scene->base.first; base; base= base->next) { + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten->directdata= base; + } + outliner_make_hierarchy(soops, &soops->tree); + } + else if(soops->outlinevis == SO_VISIBLE) { + for(base= scene->base.first; base; base= base->next) { + if(base->lay & scene->lay) + outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + } + outliner_make_hierarchy(soops, &soops->tree); + } + else if(soops->outlinevis == SO_GROUPS) { + Group *group; + GroupObject *go; + + for(group= mainvar->group.first; group; group= group->id.next) { + if(group->gobject.first) { + te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0); + + for(go= group->gobject.first; go; go= go->next) { + ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); + ten->directdata= NULL; /* eh, why? */ + } + outliner_make_hierarchy(soops, &te->subtree); + /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ + for(go= group->gobject.first; go; go= go->next) go->ob->id.newid= NULL; + } + } + } + else if(soops->outlinevis == SO_SAME_TYPE) { + Object *ob= OBACT; + if(ob) { + for(base= scene->base.first; base; base= base->next) { + if(base->object->type==ob->type) { + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten->directdata= base; + } + } + outliner_make_hierarchy(soops, &soops->tree); + } + } + else if(soops->outlinevis == SO_SELECTED) { + for(base= scene->base.first; base; base= base->next) { + if(base->lay & scene->lay) { + if(base==BASACT || (base->flag & SELECT)) { + ten= outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); + ten->directdata= base; + } + } + } + outliner_make_hierarchy(soops, &soops->tree); + } + else if(soops->outlinevis==SO_SEQUENCE) { + Sequence *seq; + Editing *ed= seq_give_editing(scene, FALSE); + int op; + + if(ed==NULL) + return; + + seq= ed->seqbasep->first; + if(!seq) + return; + + while(seq) { + op= need_add_seq_dup(seq); + if(op==1) + ten= outliner_add_element(soops, &soops->tree, (void*)seq, NULL, TSE_SEQUENCE, 0); + else if(op==0) { + ten= outliner_add_element(soops, &soops->tree, (void*)seq, NULL, TSE_SEQUENCE_DUP, 0); + outliner_add_seq_dup(soops, seq, ten, 0); + } + seq= seq->next; + } + } + else if(soops->outlinevis==SO_DATABLOCKS) { + PointerRNA mainptr; + + RNA_main_pointer_create(mainvar, &mainptr); + + ten= outliner_add_element(soops, &soops->tree, (void*)&mainptr, NULL, TSE_RNA_STRUCT, -1); + + if(show_opened) { + tselem= TREESTORE(ten); + tselem->flag &= ~TSE_CLOSED; + } + } + else if(soops->outlinevis==SO_USERDEF) { + PointerRNA userdefptr; + + RNA_pointer_create(NULL, &RNA_UserPreferences, &U, &userdefptr); + + ten= outliner_add_element(soops, &soops->tree, (void*)&userdefptr, NULL, TSE_RNA_STRUCT, -1); + + if(show_opened) { + tselem= TREESTORE(ten); + tselem->flag &= ~TSE_CLOSED; + } + } + else if(soops->outlinevis==SO_KEYMAP) { + wmWindowManager *wm= mainvar->wm.first; + wmKeyMap *km; + + for(km= wm->defaultconf->keymaps.first; km; km= km->next) { + ten= outliner_add_element(soops, &soops->tree, (void*)km, NULL, TSE_KEYMAP, 0); + } + } + else { + ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); + if(ten) ten->directdata= BASACT; + } + + outliner_sort(soops, &soops->tree); + outliner_filter_tree(soops, &soops->tree); +} + + diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 13b186b174b..603be557a3c 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -179,6 +179,13 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + case NC_ANIMATION: + switch(wmn->data) { + case ND_NLA_ACTCHANGE: + ED_region_tag_redraw(ar); + break; + } + break; } } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index b105b2507ab..14004e7fbba 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -83,9 +83,8 @@ /* avoid passing multiple args and be more verbose */ #define SEQPROP_STARTFRAME (1<<0) #define SEQPROP_ENDFRAME (1<<1) -#define SEQPROP_FILES (1<<2) -#define SEQPROP_NOPATHS (1<<3) -#define SEQPROP_NOCHAN (1<<4) +#define SEQPROP_NOPATHS (1<<2) +#define SEQPROP_NOCHAN (1<<3) #define SELECT 1 @@ -102,9 +101,6 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection"); RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips"); - - if(flag & SEQPROP_FILES) - RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); } static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, const char *identifier) @@ -411,8 +407,8 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "sound", TRUE, "Sound", "Load sound with the movie"); } @@ -466,8 +462,8 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "cache", FALSE, "Cache", "Cache the sound in memory."); } @@ -573,8 +569,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME|SEQPROP_FILES); + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILES); + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 98687bb90e0..dc84289a8de 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -702,7 +702,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline static Sequence *special_seq_update= 0; -static void set_special_seq_update(int val) +static void UNUSED_FUNCTION(set_special_seq_update)(int val) { // int x; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 6a69d32d307..e876da41bd9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -75,10 +75,6 @@ /* own include */ #include "sequencer_intern.h" -static void error(const char *UNUSED(dummy)) {} -static void waitcursor(int UNUSED(val)) {} -static void activate_fileselect(int UNUSED(d1), const char *UNUSED(d2), const char *UNUSED(d3), void *UNUSED(d4)) {} -static int pupmenu(const char *UNUSED(dummy)) {return 0;} static int okee(const char *UNUSED(dummy)) {return 0;} @@ -139,7 +135,7 @@ void seq_rectf(Sequence *seq, rctf *rectf) rectf->ymax= seq->machine+SEQ_STRIP_OFSTOP; } -static void change_plugin_seq(Scene *scene, char *str) /* called from fileselect */ +static void UNUSED_FUNCTION(change_plugin_seq)(Scene *scene, char *str) /* called from fileselect */ { Editing *ed= seq_give_editing(scene, FALSE); struct SeqEffectHandle sh; @@ -392,205 +388,6 @@ void recurs_sel_seq(Sequence *seqm) } } -int event_to_efftype(int event) -{ - if(event==2) return SEQ_CROSS; - if(event==3) return SEQ_GAMCROSS; - if(event==4) return SEQ_ADD; - if(event==5) return SEQ_SUB; - if(event==6) return SEQ_MUL; - if(event==7) return SEQ_ALPHAOVER; - if(event==8) return SEQ_ALPHAUNDER; - if(event==9) return SEQ_OVERDROP; - if(event==10) return SEQ_PLUGIN; - if(event==13) return SEQ_WIPE; - if(event==14) return SEQ_GLOW; - if(event==15) return SEQ_TRANSFORM; - if(event==16) return SEQ_COLOR; - if(event==17) return SEQ_SPEED; - if(event==18) return SEQ_ADJUSTMENT; - return 0; -} - -#if 0 -static void reload_sound_strip(Scene *scene, char *name) -{ - Editing *ed; - Sequence *seq, *seqact; - SpaceFile *sfile; - Sequence *last_seq= seq_active_get(scene); - - ed= scene->ed; - - if(last_seq==0 || last_seq->type!=SEQ_SOUND) return; - seqact= last_seq; /* last_seq changes in alloc_sequence */ - - /* search sfile */ -// sfile= scrarea_find_space_of_type(curarea, SPACE_FILE); - if(sfile==0) return; - - waitcursor(1); - - seq = sfile_to_snd_sequence(sfile, seqact->start, seqact->machine); - printf("seq->type: %i\n", seq->type); - if(seq && seq!=seqact) { - /* i'm not sure about this one, seems to work without it -- sgefant */ - seq_free_strip(seqact->strip); - - seqact->strip= seq->strip; - - seqact->len= seq->len; - calc_sequence(scene, seqact); - - seq->strip= 0; - seq_free_sequence(scene, seq); - BLI_remlink(ed->seqbasep, seq); - - seq= ed->seqbasep->first; - - } - - waitcursor(0); - -} -#endif - -static void reload_image_strip(Scene *scene, char *UNUSED(name)) -{ - Editing *ed= seq_give_editing(scene, FALSE); - Sequence *seq=NULL, *seqact; - SpaceFile *sfile=NULL; - Sequence *last_seq= seq_active_get(scene); - - - - if(last_seq==NULL || last_seq->type!=SEQ_IMAGE) return; - seqact= last_seq; /* last_seq changes in alloc_sequence */ - - /* search sfile */ -// sfile= scrarea_find_space_of_type(curarea, SPACE_FILE); - if(sfile == NULL) return; - - waitcursor(1); - -// seq= sfile_to_sequence(scene, sfile, seqact->start, seqact->machine, 1); // XXX ADD BACK - if(seq && seq!=seqact) { - seq_free_strip(seqact->strip); - - seqact->strip= seq->strip; - - seqact->len= seq->len; - calc_sequence(scene, seqact); - - seq->strip= NULL; - seq_free_sequence(scene, seq); - BLI_remlink(ed->seqbasep, seq); - - update_changed_seq_and_deps(scene, seqact, 1, 1); - } - waitcursor(0); - -} - - -static void change_sequence(Scene *scene) -{ - Editing *ed= seq_give_editing(scene, FALSE); - Sequence *last_seq= seq_active_get(scene); - Scene *sce; - short event; - - if(last_seq == NULL) return; - - if(last_seq->type & SEQ_EFFECT) { - event = pupmenu("Change Effect%t" - "|Switch A <-> B %x1" - "|Switch B <-> C %x10" - "|Plugin%x11" - "|Recalculate%x12" - "|Cross%x2" - "|Gamma Cross%x3" - "|Add%x4" - "|Sub%x5" - "|Mul%x6" - "|Alpha Over%x7" - "|Alpha Under%x8" - "|Alpha Over Drop%x9" - "|Wipe%x13" - "|Glow%x14" - "|Transform%x15" - "|Color Generator%x16" - "|Speed Control%x17" - "|Adjustment Layer%x18"); - if(event > 0) { - if(event==1) { - SWAP(Sequence *,last_seq->seq1,last_seq->seq2); - } - else if(event==10) { - SWAP(Sequence *,last_seq->seq2,last_seq->seq3); - } - else if(event==11) { - activate_fileselect( - FILE_SPECIAL, "Select Plugin", - U.plugseqdir, change_plugin_seq); - } - else if(event==12); - /* recalculate: only new_stripdata */ - else { - /* free previous effect and init new effect */ - struct SeqEffectHandle sh; - - if (get_sequence_effect_num_inputs( - last_seq->type) - < get_sequence_effect_num_inputs( - event_to_efftype(event))) { - error("New effect needs more " - "input strips!"); - } else { - sh = get_sequence_effect(last_seq); - sh.free(last_seq); - - last_seq->type - = event_to_efftype(event); - - sh = get_sequence_effect(last_seq); - sh.init(last_seq); - } - } - - update_changed_seq_and_deps(scene, last_seq, 0, 1); - } - } - else if(last_seq->type == SEQ_IMAGE) { - if(okee("Change images")) { - activate_fileselect(FILE_SPECIAL, - "Select Images", - ed->act_imagedir, - reload_image_strip); - } - } - else if(last_seq->type == SEQ_MOVIE) { - ; - } - else if(last_seq->type == SEQ_SCENE) { - event= pupmenu("Change Scene%t|Update Start and End"); - - if(event==1) { - sce= last_seq->scene; - - last_seq->len= sce->r.efra - sce->r.sfra + 1; - last_seq->sfra= sce->r.sfra; - - /* bad code to change seq->len? update_changed_seq_and_deps() expects the strip->len to be OK */ - new_tstripdata(last_seq); - - update_changed_seq_and_deps(scene, last_seq, 1, 1); - - } - } - -} - int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str) { Editing *ed = seq_give_editing(scene, FALSE); @@ -961,7 +758,7 @@ static int insert_gap(Scene *scene, int gap, int cfra) return done; } -static void touch_seq_files(Scene *scene) +static void UNUSED_FUNCTION(touch_seq_files)(Scene *scene) { Sequence *seq; Editing *ed= seq_give_editing(scene, FALSE); @@ -973,7 +770,7 @@ static void touch_seq_files(Scene *scene) if(okee("Touch and print selected movies")==0) return; - waitcursor(1); + WM_cursor_wait(1); SEQP_BEGIN(ed, seq) { if(seq->flag & SELECT) { @@ -988,7 +785,7 @@ static void touch_seq_files(Scene *scene) } SEQ_END - waitcursor(0); + WM_cursor_wait(0); } /* @@ -1016,7 +813,7 @@ static void set_filter_seq(Scene *scene) } */ -static void seq_remap_paths(Scene *scene) +static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene) { Sequence *seq, *last_seq = seq_active_get(scene); Editing *ed= seq_give_editing(scene, FALSE); @@ -1057,7 +854,7 @@ static void seq_remap_paths(Scene *scene) } -static void no_gaps(Scene *scene) +static void UNUSED_FUNCTION(no_gaps)(Scene *scene) { Editing *ed= seq_give_editing(scene, FALSE); int cfra, first= 0, done; @@ -1103,6 +900,19 @@ int sequencer_edit_poll(bContext *C) return (seq_give_editing(CTX_data_scene(C), FALSE) != NULL); } +int sequencer_strip_poll(bContext *C) +{ + Editing *ed; + return (((ed= seq_give_editing(CTX_data_scene(C), FALSE)) != NULL) && (ed->act_seq != NULL)); +} + +int sequencer_strip_has_path_poll(bContext *C) +{ + Editing *ed; + Sequence *seq; + return (((ed= seq_give_editing(CTX_data_scene(C), FALSE)) != NULL) && ((seq= ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq))); +} + int sequencer_view_poll(bContext *C) { SpaceSeq *sseq= CTX_wm_space_seq(C); @@ -1392,7 +1202,7 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot) ot->poll= sequencer_edit_poll; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */ } /* reload operator */ @@ -1418,9 +1228,6 @@ void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot) /* api callbacks */ ot->exec= sequencer_refresh_all_exec; ot->poll= sequencer_edit_poll; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) @@ -1755,6 +1562,58 @@ void SEQUENCER_OT_delete(wmOperatorType *ot) } +/* offset clear operator */ +static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene= CTX_data_scene(C); + Editing *ed= seq_give_editing(scene, FALSE); + Sequence *seq; + + /* for effects, try to find a replacement input */ + for(seq=ed->seqbasep->first; seq; seq=seq->next) { + if((seq->type & SEQ_EFFECT)==0 && (seq->flag & SELECT)) { + seq->startofs= seq->endofs= seq->startstill= seq->endstill= 0; + } + } + + /* updates lengths etc */ + seq= ed->seqbasep->first; + while(seq) { + calc_sequence(scene, seq); + seq= seq->next; + } + + for(seq=ed->seqbasep->first; seq; seq=seq->next) { + if((seq->type & SEQ_EFFECT)==0 && (seq->flag & SELECT)) { + if(seq_test_overlap(ed->seqbasep, seq)) { + shuffle_seq(ed->seqbasep, seq, scene); + } + } + } + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + + +void SEQUENCER_OT_offset_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Clear Strip Offset"; + ot->idname= "SEQUENCER_OT_offset_clear"; + ot->description="Clear strip offsets from the start and end frames"; + + /* api callbacks */ + ot->exec= sequencer_offset_clear_exec; + ot->poll= sequencer_edit_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + + /* separate_images operator */ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) { @@ -2663,7 +2522,7 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) ot->poll= sequencer_edit_poll; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER; /* properties */ } @@ -2830,3 +2689,230 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot) /* rna */ WM_operator_properties_gesture_border(ot, FALSE); } + + +/* change ops */ + +static EnumPropertyItem prop_change_effect_input_types[] = { + {0, "A_B", 0, "A -> B", ""}, + {1, "B_C", 0, "B -> C", ""}, + {2, "A_C", 0, "A -> C", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Editing *ed= seq_give_editing(scene, FALSE); + Sequence *seq= seq_active_get(scene); + + Sequence **seq_1, **seq_2; + + switch(RNA_enum_get(op->ptr, "swap")) { + case 0: + seq_1= &seq->seq1; + seq_2= &seq->seq2; + break; + case 1: + seq_1= &seq->seq2; + seq_2= &seq->seq3; + break; + default: /* 2 */ + seq_1= &seq->seq1; + seq_2= &seq->seq3; + break; + } + + if(*seq_1 == NULL || *seq_2 == NULL) { + BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, can't swap"); + return OPERATOR_CANCELLED; + } + else { + SWAP(Sequence *, *seq_1, *seq_2); + } + + update_changed_seq_and_deps(scene, seq, 0, 1); + + /* important else we dont get the imbuf cache flushed */ + free_imbuf_seq(scene, &ed->seqbase, FALSE, FALSE); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change Effect Input"; + ot->idname= "SEQUENCER_OT_change_effect_input"; + ot->description=""; + + /* api callbacks */ + ot->exec= sequencer_change_effect_input_exec; + ot->poll= sequencer_effect_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + ot->prop= RNA_def_enum(ot->srna, "swap", prop_change_effect_input_types, 0, "Swap", "The effect inputs to swap"); +} + +static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Editing *ed= seq_give_editing(scene, FALSE); + Sequence *seq= seq_active_get(scene); + const int new_type= RNA_enum_get(op->ptr, "type"); + + /* free previous effect and init new effect */ + struct SeqEffectHandle sh; + + if ((seq->type & SEQ_EFFECT) == 0) { + return OPERATOR_CANCELLED; + } + + /* can someone explain the logic behind only allowing to increse this, + * copied from 2.4x - campbell */ + if (get_sequence_effect_num_inputs(seq->type) < + get_sequence_effect_num_inputs(new_type) + ) { + BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips"); + return OPERATOR_CANCELLED; + } + else { + sh = get_sequence_effect(seq); + sh.free(seq); + + seq->type= new_type; + + sh = get_sequence_effect(seq); + sh.init(seq); + } + + /* update */ + update_changed_seq_and_deps(scene, seq, 0, 1); + + /* important else we dont get the imbuf cache flushed */ + free_imbuf_seq(scene, &ed->seqbase, FALSE, FALSE); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change Effect Type"; + ot->idname= "SEQUENCER_OT_change_effect_type"; + ot->description=""; + + /* api callbacks */ + ot->exec= sequencer_change_effect_type_exec; + ot->poll= sequencer_effect_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + ot->prop= RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); +} + +static int sequencer_change_path_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Editing *ed= seq_give_editing(scene, FALSE); + Sequence *seq= seq_active_get(scene); + + if(seq->type == SEQ_IMAGE) { + char directory[FILE_MAX]; + const int len= RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); + StripElem *se; + + if(len==0) + return OPERATOR_CANCELLED; + + RNA_string_get(op->ptr, "directory", directory); + BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir)); + + if(seq->strip->stripdata) { + MEM_freeN(seq->strip->stripdata); + } + seq->strip->stripdata= se= MEM_callocN(len*sizeof(StripElem), "stripelem"); + + RNA_BEGIN(op->ptr, itemptr, "files") { + char *filename= RNA_string_get_alloc(&itemptr, "name", NULL, 0); + BLI_strncpy(se->name, filename, sizeof(se->name)); + MEM_freeN(filename); + se++; + } + RNA_END; + + /* reset these else we wont see all the images */ + seq->anim_startofs= seq->anim_endofs= 0; + + /* correct start/end frames so we dont move + * important not to set seq->len= len; allow the function to handle it */ + reload_sequence_new_file(scene, seq, TRUE); + + calc_sequence(scene, seq); + + /* important else we dont get the imbuf cache flushed */ + free_imbuf_seq(scene, &ed->seqbase, FALSE, FALSE); + } + else { + /* lame, set rna filepath */ + PointerRNA seq_ptr; + PropertyRNA *prop; + char filepath[FILE_MAX]; + + RNA_pointer_create(&scene->id, &RNA_Sequence, seq, &seq_ptr); + + RNA_string_get(op->ptr, "filepath", filepath); + prop= RNA_struct_find_property(&seq_ptr, "filepath"); + RNA_property_string_set(&seq_ptr, prop, filepath); + RNA_property_update(C, &seq_ptr, prop); + } + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + Scene *scene= CTX_data_scene(C); + Sequence *seq= seq_active_get(scene); + + RNA_string_set(op->ptr, "directory", seq->strip->dir); + + /* set default display depending on seq type */ + if(seq->type == SEQ_IMAGE) { + RNA_boolean_set(op->ptr, "filter_movie", 0); + } + else { + RNA_boolean_set(op->ptr, "filter_image", 0); + } + + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +void SEQUENCER_OT_change_path(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change Data/Files"; + ot->idname= "SEQUENCER_OT_change_path"; + ot->description=""; + + /* api callbacks */ + ot->exec= sequencer_change_path_exec; + ot->invoke= sequencer_change_path_invoke; + ot->poll= sequencer_strip_has_path_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_DIRECTORY|WM_FILESEL_RELPATH|WM_FILESEL_FILEPATH|WM_FILESEL_FILES); +} diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 209b39662aa..7ab76f9b6d7 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -70,6 +70,8 @@ int seq_effect_find_selected(struct Scene *scene, struct Sequence *activeseq, in /* operator helpers */ int sequencer_edit_poll(struct bContext *C); +int sequencer_strip_poll(struct bContext *C); +int sequencer_strip_has_path_poll(struct bContext *C); int sequencer_view_poll(struct bContext *C); /* externs */ @@ -91,6 +93,7 @@ void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot); void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot); void SEQUENCER_OT_duplicate(struct wmOperatorType *ot); void SEQUENCER_OT_delete(struct wmOperatorType *ot); +void SEQUENCER_OT_offset_clear(struct wmOperatorType *ot); void SEQUENCER_OT_images_separate(struct wmOperatorType *ot); void SEQUENCER_OT_meta_toggle(struct wmOperatorType *ot); void SEQUENCER_OT_meta_make(struct wmOperatorType *ot); @@ -108,6 +111,10 @@ void SEQUENCER_OT_view_selected(struct wmOperatorType *ot); void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot); void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot); +void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot); +void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot); +void SEQUENCER_OT_change_path(struct wmOperatorType *ot); + void SEQUENCER_OT_copy(struct wmOperatorType *ot); void SEQUENCER_OT_paste(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index f5c26cb17d3..df33ce73b9c 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -68,6 +68,7 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_swap_inputs); WM_operatortype_append(SEQUENCER_OT_duplicate); WM_operatortype_append(SEQUENCER_OT_delete); + WM_operatortype_append(SEQUENCER_OT_offset_clear); WM_operatortype_append(SEQUENCER_OT_images_separate); WM_operatortype_append(SEQUENCER_OT_meta_toggle); WM_operatortype_append(SEQUENCER_OT_meta_make); @@ -86,6 +87,10 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_view_zoom_ratio); WM_operatortype_append(SEQUENCER_OT_view_ghost_border); + WM_operatortype_append(SEQUENCER_OT_change_effect_input); + WM_operatortype_append(SEQUENCER_OT_change_effect_type); + WM_operatortype_append(SEQUENCER_OT_change_path); + /* sequencer_select.c */ WM_operatortype_append(SEQUENCER_OT_select_all_toggle); WM_operatortype_append(SEQUENCER_OT_select_inverse); @@ -145,6 +150,8 @@ void sequencer_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SEQUENCER_OT_reassign_inputs", RKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_reload", RKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "SEQUENCER_OT_offset_clear", OKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "SEQUENCER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", XKEY, KM_PRESS, 0, 0); @@ -240,6 +247,8 @@ void sequencer_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SEQUENCER_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "SEQUENCER_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); + + WM_keymap_add_menu(keymap, "SEQUENCER_MT_change", CKEY, KM_PRESS, 0, 0); kmi= WM_keymap_add_item(keymap, "WM_OT_context_set_int", OKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "scene.sequence_editor.overlay_frame"); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 8d5f372f55e..0ac23765167 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -159,7 +159,7 @@ void select_surround_from_last(Scene *scene) #endif -static void select_single_seq(Scene *scene, Sequence *seq, int deselect_all) /* BRING BACK */ +static void UNUSED_FUNCTION(select_single_seq)(Scene *scene, Sequence *seq, int deselect_all) /* BRING BACK */ { Editing *ed= seq_give_editing(scene, FALSE); diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c index 6e6f131655b..51b4b838171 100644 --- a/source/blender/editors/space_text/text_python.c +++ b/source/blender/editors/space_text/text_python.c @@ -43,6 +43,7 @@ #include "BKE_text.h" #include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "WM_types.h" @@ -192,7 +193,7 @@ static void confirm_suggestion(Text *text, int skipleft) // XXX static int doc_scroll= 0; -static short do_texttools(SpaceText *st, char ascii, unsigned short evnt, short val) +static short UNUSED_FUNCTION(do_texttools)(SpaceText *st, char ascii, unsigned short evnt, short val) { ARegion *ar= NULL; // XXX int qual= 0; // XXX @@ -375,7 +376,7 @@ static short do_texttools(SpaceText *st, char ascii, unsigned short evnt, short ; // XXX redraw_alltext(); #endif -static short do_textmarkers(SpaceText *st, char ascii, unsigned short evnt, short val) +static short UNUSED_FUNCTION(do_textmarkers)(SpaceText *st, char ascii, unsigned short evnt, short val) { Text *text; TextMarker *marker, *mrk, *nxt; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 7e9a3411171..3cc11df8a40 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -29,7 +29,6 @@ * \ingroup spview3d */ - #include <string.h> #include <math.h> @@ -70,24 +69,21 @@ #include "view3d_intern.h" // own include -/***/ +/**************************** Face Select Mode *******************************/ - /* Flags for marked edges */ +/* Flags for marked edges */ enum { eEdge_Visible = (1<<0), eEdge_Select = (1<<1), }; - /* Creates a hash of edges to flags indicating - * adjacent tface select/active/etc flags. - */ +/* Creates a hash of edges to flags indicating selected/visible */ static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags) { int *flags_p; - if (!BLI_edgehash_haskey(eh, v0, v1)) { + if(!BLI_edgehash_haskey(eh, v0, v1)) BLI_edgehash_insert(eh, v0, v1, NULL); - } flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1); *flags_p |= flags; @@ -96,26 +92,25 @@ static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flag static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me) { EdgeHash *eh = BLI_edgehash_new(); - int i; MFace *mf; + int i; - for (i=0; i<me->totface; i++) { + for(i=0; i<me->totface; i++) { mf = &me->mface[i]; - if (mf->v3) { - if (!(mf->flag&ME_HIDE)) { - unsigned int flags = eEdge_Visible; - if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select; - - get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags); - get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags); - if (mf->v4) { - get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags); - get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags); - } else { - get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags); - } + if(!(mf->flag & ME_HIDE)) { + unsigned int flags = eEdge_Visible; + if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select; + + get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags); + get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags); + + if(mf->v4) { + get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags); + get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags); } + else + get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags); } } @@ -123,45 +118,24 @@ static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me) } -static int draw_tfaces3D__setHiddenOpts(void *userData, int index) +static int draw_mesh_face_select__setHiddenOpts(void *userData, int index) { struct { Mesh *me; EdgeHash *eh; } *data = userData; Mesh *me= data->me; MEdge *med = &me->medge[index]; uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); - if((me->drawflag & ME_DRAWSEAMS) && (med->flag&ME_SEAM)) { - return 0; - } else if(me->drawflag & ME_DRAWEDGES){ - if (me->drawflag & ME_HIDDENEDGES) { + if(me->drawflag & ME_DRAWEDGES) { + if(me->drawflag & ME_HIDDENEDGES) return 1; - } else { - return (flags & eEdge_Visible); - } - } else { - return (flags & eEdge_Select); - } -} - -static int draw_tfaces3D__setSeamOpts(void *userData, int index) -{ - struct { Mesh *me; EdgeHash *eh; } *data = userData; - Mesh *me= data->me; - MEdge *med = &data->me->medge[index]; - uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); - - if (med->flag & ME_SEAM) { - if (me->drawflag & ME_HIDDENEDGES) { - return 1; - } else { + else return (flags & eEdge_Visible); - } - } else { - return 0; } + else + return (flags & eEdge_Select); } -static int draw_tfaces3D__setSelectOpts(void *userData, int index) +static int draw_mesh_face_select__setSelectOpts(void *userData, int index) { struct { Mesh *me; EdgeHash *eh; } *data = userData; MEdge *med = &data->me->medge[index]; @@ -170,45 +144,19 @@ static int draw_tfaces3D__setSelectOpts(void *userData, int index) return flags & eEdge_Select; } -#if 0 -static int draw_tfaces3D__setActiveOpts(void *userData, int index) -{ - struct { Mesh *me; EdgeHash *eh; } *data = userData; - MEdge *med = &data->me->medge[index]; - uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); - - if (flags & eEdge_Select) { - return 1; - } else { - return 0; - } -} - -static int draw_tfaces3D__drawFaceOpts(void *userData, int index) -{ - Mesh *me = (Mesh*)userData; - - MFace *mface = &me->mface[index]; - if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL)) - return 2; /* Don't set color */ - else - return 0; -} -#endif - /* draws unselected */ -static int draw_tfaces3D__drawFaceOptsInv(void *userData, int index) +static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index) { Mesh *me = (Mesh*)userData; MFace *mface = &me->mface[index]; - if (!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL)) + if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL)) return 2; /* Don't set color */ else return 0; } -static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short draw_seams) +static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) { struct { Mesh *me; EdgeHash *eh; } data; @@ -222,30 +170,16 @@ static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short d /* Draw (Hidden) Edges */ setlinestyle(1); UI_ThemeColor(TH_EDGE_FACESEL); - dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data); + dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data); setlinestyle(0); - /* Draw Seams */ - if(draw_seams && me->drawflag & ME_DRAWSEAMS) { - UI_ThemeColor(TH_EDGE_SEAM); - glLineWidth(2); - dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data); - glLineWidth(1); - } - /* Draw Selected Faces */ if(me->drawflag & ME_DRAWFACES) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#if 0 - UI_ThemeColor4(TH_FACE_SELECT); - - dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me); -#else /* dull unselected faces so as not to get in the way of seeing color */ glColor4ub(96, 96, 96, 64); - dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOptsInv, (void*)me); -#endif + dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, (void*)me); glDisable(GL_BLEND); } @@ -255,7 +189,7 @@ static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short d /* Draw Stippled Outline for selected faces */ glColor3ub(255, 255, 255); setlinestyle(1); - dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data); + dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); setlinestyle(0); bglPolygonOffset(rv3d->dist, 0.0); // resets correctly now, even after calling accumulated offsets @@ -263,6 +197,8 @@ static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short d BLI_edgehash_free(data.eh, NULL); } +/***************************** Texture Drawing ******************************/ + static Material *give_current_material_or_def(Object *ob, int matnr) { extern Material defmaterial; // render module abuse... @@ -673,21 +609,24 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o if(ob->mode & OB_MODE_EDIT) { dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh); - } else if(draw_flags & DRAW_IS_PAINT_SEL) { + } + else if(draw_flags & DRAW_IS_PAINT_SEL) { if(ob->mode & OB_MODE_WEIGHT_PAINT) dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material); else dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me); } else { - if( GPU_buffer_legacy(dm) ) + if(GPU_buffer_legacy(dm)) { if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW) dm->drawFacesTex(dm, draw_mcol__set_draw_legacy); else dm->drawFacesTex(dm, draw_tface__set_draw_legacy); + } else { - if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) ) + if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL)) add_tface_color_layer(dm); + dm->drawFacesTex(dm, draw_tface__set_draw); } } @@ -700,7 +639,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o /* draw edges and selected faces over textured mesh */ if(!(ob == scene->obedit) && (draw_flags & DRAW_IS_PAINT_SEL)) - draw_tfaces3D(rv3d, me, dm, ob->mode & OB_MODE_WEIGHT_PAINT); + draw_mesh_face_select(rv3d, me, dm); /* reset from negative scale correction */ glFrontFace(GL_CCW); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 4b5166f6a23..62fe8492597 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2368,7 +2368,20 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E } } } - + + /* useful for debugging index vs shape key index */ +#if 0 + { + EditVert *eve; + int j; + UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); + for(eve= em->verts.first, j= 0; eve; eve= eve->next, j++) { + sprintf(val, "%d:%d", j, eve->keyindex); + view3d_cached_text_draw_add(eve->co, val, 0, V3D_CACHE_TEXT_ASCII, col); + } + } +#endif + if(v3d->zbuf) { glEnable(GL_DEPTH_TEST); bglPolygonOffset(rv3d->dist, 0.0f); @@ -5526,7 +5539,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) } } else if(ob->type==OB_ARMATURE) { - if(!(ob->mode & OB_MODE_POSE)) + if(!(ob->mode & OB_MODE_POSE && base == scene->basact)) draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, TRUE); } @@ -5783,7 +5796,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */ /* draw motion paths (in view space) */ - if (ob->mpath) { + if (ob->mpath && (v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { bAnimVizSettings *avs= &ob->avs; /* setup drawing environment for paths */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6e3f6549ba3..f8837594ddb 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -721,7 +721,7 @@ static void draw_rotation_guide(RegionView3D *rv3d) { #define ROT_AXIS_DETAIL 13 const float s = 0.05f * scale; - const float step = 2.f * M_PI / ROT_AXIS_DETAIL; + const float step = 2.f * (float)(M_PI / ROT_AXIS_DETAIL); float angle; int i; @@ -1041,7 +1041,7 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons glBegin(GL_LINES); if(w > h) { if(golden) { - ofs = w * (1.0f-(1.0f/1.61803399)); + ofs = w * (1.0f-(1.0f/1.61803399f)); } else { ofs = h * (h / w); @@ -1059,7 +1059,7 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons } else { if(golden) { - ofs = h * (1.0f-(1.0f/1.61803399)); + ofs = h * (1.0f-(1.0f/1.61803399f)); } else { ofs = w * (w / h); @@ -1203,7 +1203,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (ca->dtx & CAM_DTX_GOLDEN) { UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); - drawviewborder_grid3(x1, x2, y1, y2, 1.0f-(1.0f/1.61803399)); + drawviewborder_grid3(x1, x2, y1, y2, 1.0f-(1.0f/1.61803399f)); } if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) { @@ -2769,3 +2769,4 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) v3d->flag |= V3D_INVALID_BACKBUF; } + diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e6fd9e8867b..979a602b4f5 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -949,134 +949,125 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event // -- zooming // -- panning in rotationally-locked views { - RegionView3D* rv3d = CTX_wm_region_view3d(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + RegionView3D* rv3d = CTX_wm_region_view3d(C); + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; - rv3d->rot_angle = 0.f; // off by default, until changed later this function + rv3d->rot_angle = 0.f; // off by default, until changed later this function - if (ndof->progress != P_FINISHING) { - const float dt = ndof->dt; - - // tune these until everything feels right - const float rot_sensitivity = 1.f; - const float zoom_sensitivity = 1.f; - const float pan_sensitivity = 1.f; - - // rather have bool, but... - int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); - - float view_inv[4]; - invert_qt_qt(view_inv, rv3d->viewquat); - - //#define DEBUG_NDOF_MOTION - #ifdef DEBUG_NDOF_MOTION - printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", - ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); - #endif - - if (ndof->tvec[2]) { - // Zoom! - // velocity should be proportional to the linear velocity attained by rotational motion of same strength - // [got that?] - // proportional to arclength = radius * angle - - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; - rv3d->dist += zoom_distance; - } - - if (rv3d->viewlock == RV3D_LOCKED) { - /* rotation not allowed -- explore panning options instead */ - float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; - mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); - - /* transform motion from view to world coordinates */ + if (ndof->progress != P_FINISHING) { + const float dt = ndof->dt; + + // tune these until everything feels right + const float rot_sensitivity = 1.f; + const float zoom_sensitivity = 1.f; + const float pan_sensitivity = 1.f; + + // rather have bool, but... + int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec); + + float view_inv[4]; invert_qt_qt(view_inv, rv3d->viewquat); - mul_qt_v3(view_inv, pan_vec); - - /* move center of view opposite of hand motion (this is camera mode, not object mode) */ - sub_v3_v3(rv3d->ofs, pan_vec); - } - - if (has_rotation) { - - const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; - - rv3d->view = RV3D_VIEW_USER; - - if (U.flag & USER_TRACKBALL) { - float rot[4]; - #if 0 // -------------------------- Mike's nifty original version - float view_inv_conj[4]; - - ndof_to_quat(ndof, rot); - // mul_qt_fl(rot, rot_sensitivity); - // ^^ no apparent effect - - if (invert) - invert_qt(rot); - - copy_qt_qt(view_inv_conj, view_inv); - conjugate_qt(view_inv_conj); - - // transform rotation from view to world coordinates - mul_qt_qtqt(rot, view_inv, rot); - mul_qt_qtqt(rot, rot, view_inv_conj); - #else // ---------------------------------------- Mike's revised version - float axis[3]; - float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); - - if (invert) - angle = -angle; - - // transform rotation axis from view to world coordinates - mul_qt_v3(view_inv, axis); - - // update the onscreen doo-dad - rv3d->rot_angle = angle; - copy_v3_v3(rv3d->rot_axis, axis); - - axis_angle_to_quat(rot, axis, angle); - #endif // -------------------------------------------- - // apply rotation - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - } else { - /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ - float angle, rot[4]; - float xvec[3] = {1,0,0}; - - /* Determine the direction of the x vector (for rotating up and down) */ - mul_qt_v3(view_inv, xvec); - - /* Perform the up/down rotation */ - angle = rot_sensitivity * dt * ndof->rvec[0]; - if (invert) - angle = -angle; - rot[0] = cos(angle); - mul_v3_v3fl(rot+1, xvec, sin(angle)); - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); - - /* Perform the orbital rotation */ - angle = rot_sensitivity * dt * ndof->rvec[1]; - if (invert) - angle = -angle; - - // update the onscreen doo-dad - rv3d->rot_angle = angle; - rv3d->rot_axis[0] = 0; - rv3d->rot_axis[1] = 0; - rv3d->rot_axis[2] = 1; - - rot[0] = cos(angle); - rot[1] = rot[2] = 0.0; - rot[3] = sin(angle); - mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + //#define DEBUG_NDOF_MOTION + #ifdef DEBUG_NDOF_MOTION + printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n", + ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt); + #endif + + if (ndof->tvec[2]) { + // Zoom! + // velocity should be proportional to the linear velocity attained by rotational motion of same strength + // [got that?] + // proportional to arclength = radius * angle + + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2]; + + if (U.ndof_flag & NDOF_ZOOM_INVERT) + zoom_distance = -zoom_distance; + + rv3d->dist += zoom_distance; + } + + if (rv3d->viewlock == RV3D_LOCKED) { + /* rotation not allowed -- explore panning options instead */ + float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f}; + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); + + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); + + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + } + + if (has_rotation) { + + const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES; + + rv3d->view = RV3D_VIEW_USER; + + if (U.flag & USER_TRACKBALL) { + float rot[4]; + float axis[3]; + float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (invert) + angle = -angle; + + // transform rotation axis from view to world coordinates + mul_qt_v3(view_inv, axis); + + // update the onscreen doo-dad + rv3d->rot_angle = angle; + copy_v3_v3(rv3d->rot_axis, axis); + + axis_angle_to_quat(rot, axis, angle); + + // apply rotation + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } else { + /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */ + float angle, rot[4]; + float xvec[3] = {1,0,0}; + + /* Determine the direction of the x vector (for rotating up and down) */ + mul_qt_v3(view_inv, xvec); + + /* Perform the up/down rotation */ + angle = rot_sensitivity * dt * ndof->rvec[0]; + if (invert) + angle = -angle; + rot[0] = cos(angle); + mul_v3_v3fl(rot+1, xvec, sin(angle)); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + + /* Perform the orbital rotation */ + angle = rot_sensitivity * dt * ndof->rvec[1]; + if (invert) + angle = -angle; + + // update the onscreen doo-dad + rv3d->rot_angle = angle; + rv3d->rot_axis[0] = 0; + rv3d->rot_axis[1] = 0; + rv3d->rot_axis[2] = 1; + + rot[0] = cos(angle); + rot[1] = rot[2] = 0.0; + rot[3] = sin(angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot); + } } } - } - ED_region_tag_redraw(CTX_wm_region(C)); + ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; + } } void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot) @@ -1098,57 +1089,62 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) // -- "pan" navigation // -- zoom or dolly? { - RegionView3D* rv3d = CTX_wm_region_view3d(C); - wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + if (event->type != NDOF_MOTION) + return OPERATOR_CANCELLED; + else { + RegionView3D* rv3d = CTX_wm_region_view3d(C); + wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata; + - rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators + rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators - if (ndof->progress != P_FINISHING) { - const float dt = ndof->dt; - float view_inv[4]; + if (ndof->progress != P_FINISHING) { + const float dt = ndof->dt; + float view_inv[4]; #if 0 // ------------------------------------------- zoom with Z - // tune these until everything feels right - const float zoom_sensitivity = 1.f; - const float pan_sensitivity = 1.f; - - float pan_vec[3] = { - ndof->tx, ndof->ty, 0 - }; - - // "zoom in" or "translate"? depends on zoom mode in user settings? - if (ndof->tz) { - float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; - rv3d->dist += zoom_distance; - } - - mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); + // tune these until everything feels right + const float zoom_sensitivity = 1.f; + const float pan_sensitivity = 1.f; + + float pan_vec[3] = { + ndof->tx, ndof->ty, 0 + }; + + // "zoom in" or "translate"? depends on zoom mode in user settings? + if (ndof->tz) { + float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz; + rv3d->dist += zoom_distance; + } + + mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt); #else // ------------------------------------------------------- dolly with Z - float speed = 10.f; // blender units per second - // ^^ this is ok for default cube scene, but should scale with.. something + float speed = 10.f; // blender units per second + // ^^ this is ok for default cube scene, but should scale with.. something - // tune these until everything feels right - const float forward_sensitivity = 1.f; - const float vertical_sensitivity = 0.4f; - const float lateral_sensitivity = 0.6f; + // tune these until everything feels right + const float forward_sensitivity = 1.f; + const float vertical_sensitivity = 0.4f; + const float lateral_sensitivity = 0.6f; - float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0], - vertical_sensitivity * ndof->tvec[1], - forward_sensitivity * ndof->tvec[2] - }; + float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0], + vertical_sensitivity * ndof->tvec[1], + forward_sensitivity * ndof->tvec[2] + }; - mul_v3_fl(pan_vec, speed * dt); + mul_v3_fl(pan_vec, speed * dt); #endif - /* transform motion from view to world coordinates */ - invert_qt_qt(view_inv, rv3d->viewquat); - mul_qt_v3(view_inv, pan_vec); + /* transform motion from view to world coordinates */ + invert_qt_qt(view_inv, rv3d->viewquat); + mul_qt_v3(view_inv, pan_vec); - /* move center of view opposite of hand motion (this is camera mode, not object mode) */ - sub_v3_v3(rv3d->ofs, pan_vec); - } + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, pan_vec); + } - ED_region_tag_redraw(CTX_wm_region(C)); + ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; + } } void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot) @@ -1701,7 +1697,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) static void view_dolly_mouseloc(ARegion *ar, float orig_ofs[3], float dvec[3], float dfac) { RegionView3D *rv3d= ar->regiondata; - madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0 - dfac)); + madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac)); } static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_invert) @@ -1722,7 +1718,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv if (zoom_invert) SWAP(float, len1, len2); - zfac = 1.0 + ((len2 - len1) * 0.01 * vod->rv3d->dist); + zfac = 1.0f + ((len2 - len1) * 0.01f * vod->rv3d->dist); } if(zfac != 1.0f) diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 046037a092f..30d1a508888 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -867,7 +867,7 @@ static int flyApply(bContext *C, FlyInfo *fly) upvec[2]=1; mul_m3_v3(mat, upvec); /*make sure we have some z rolling*/ - if (fabs(upvec[2]) > 0.00001f) { + if (fabsf(upvec[2]) > 0.00001f) { roll= upvec[2] * -5.0f; upvec[0]= 1.0f; /*rotate the view about this axis*/ diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 5b95ae63e56..78dcf6c9a5c 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -281,31 +281,32 @@ static char *view3d_modeselect_pup(Scene *scene) str += sprintf(str, formatstr, "Object Mode", OB_MODE_OBJECT, ICON_OBJECT_DATA); if(ob==NULL || ob->data==NULL) return string; - if(ob->id.lib || ((ID *)ob->data)->lib) return string; + if(ob->id.lib) return string; - /* if active object is editable */ - if ( ((ob->type == OB_MESH) - || (ob->type == OB_CURVE) || (ob->type == OB_SURF) || (ob->type == OB_FONT) - || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) { - - str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); - } - else if (ob->type == OB_ARMATURE) { - if (ob->mode & OB_MODE_POSE) - str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT|OB_MODE_POSE, ICON_EDITMODE_HLT); - else + if(!((ID *)ob->data)->lib) { + /* if active object is editable */ + if ( ((ob->type == OB_MESH) + || (ob->type == OB_CURVE) || (ob->type == OB_SURF) || (ob->type == OB_FONT) + || (ob->type == OB_MBALL) || (ob->type == OB_LATTICE))) { + str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); - } + } + else if (ob->type == OB_ARMATURE) { + if (ob->mode & OB_MODE_POSE) + str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT|OB_MODE_POSE, ICON_EDITMODE_HLT); + else + str += sprintf(str, formatstr, "Edit Mode", OB_MODE_EDIT, ICON_EDITMODE_HLT); + } - if (ob->type == OB_MESH) { + if (ob->type == OB_MESH) { - str += sprintf(str, formatstr, "Sculpt Mode", OB_MODE_SCULPT, ICON_SCULPTMODE_HLT); - str += sprintf(str, formatstr, "Vertex Paint", OB_MODE_VERTEX_PAINT, ICON_VPAINT_HLT); - str += sprintf(str, formatstr, "Texture Paint", OB_MODE_TEXTURE_PAINT, ICON_TPAINT_HLT); - str += sprintf(str, formatstr, "Weight Paint", OB_MODE_WEIGHT_PAINT, ICON_WPAINT_HLT); + str += sprintf(str, formatstr, "Sculpt Mode", OB_MODE_SCULPT, ICON_SCULPTMODE_HLT); + str += sprintf(str, formatstr, "Vertex Paint", OB_MODE_VERTEX_PAINT, ICON_VPAINT_HLT); + str += sprintf(str, formatstr, "Texture Paint", OB_MODE_TEXTURE_PAINT, ICON_TPAINT_HLT); + str += sprintf(str, formatstr, "Weight Paint", OB_MODE_WEIGHT_PAINT, ICON_WPAINT_HLT); + } } - - + /* if active object is an armature */ if (ob->type==OB_ARMATURE) { str += sprintf(str, formatstr, "Pose Mode", OB_MODE_POSE, ICON_POSE_HLT); @@ -465,6 +466,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) Object *ob= OBACT; Object *obedit = CTX_data_edit_object(C); uiBlock *block; + uiBut *but; uiLayout *row; const float dpi_fac= UI_DPI_FAC; @@ -512,9 +514,12 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) block= uiLayoutGetBlock(row); if(v3d->twflag & V3D_USE_MANIPULATOR) { - uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode"); - uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode"); - uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode"); + but= uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode"); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + but= uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode"); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ + but= uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode"); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ } if (v3d->twmode > (BIF_countTransformOrientation(C) - 1) + V3D_MANIP_CUSTOM) { @@ -522,7 +527,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) } str_menu = BIF_menustringTransformOrientation(C, "Orientation"); - uiDefButC(block, MENU, B_MAN_MODE, str_menu,0,0,70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation"); + but= uiDefButC(block, MENU, B_MAN_MODE, str_menu,0,0,70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation"); + uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ MEM_freeN((void *)str_menu); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c6835b0cad3..86112a42d99 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1335,9 +1335,9 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce if(oldbasact != basact) { ED_base_object_activate(C, basact); /* adds notifier */ } - - WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); } + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); } return retval; @@ -1841,8 +1841,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) int retval = 0; view3d_operator_needs_opengl(C); - - if(obedit) { + + if(obedit && center==FALSE) { if(obedit->type==OB_MESH) retval = mouse_mesh(C, event->mval, extend); else if(obedit->type==OB_ARMATURE) @@ -1889,7 +1889,7 @@ void VIEW3D_OT_select(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first."); - RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting (object mode only)."); + RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting, in editmode used to extend object selection."); RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only)."); } diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 2e96800bf3b..a2aed67821d 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -46,6 +46,7 @@ #include "BLI_editVert.h" #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -140,10 +141,11 @@ static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2) static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { - wmOperatorType *ot = WM_operatortype_first(); - - for(; ot; ot= ot->next) { - + GHashIterator *iter= WM_operatortype_iter(); + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + wmOperatorType *ot= BLI_ghashIterator_getValue(iter); + if(BLI_strcasestr(ot->name, str)) { if(WM_operator_poll((bContext*)C, ot)) { @@ -152,6 +154,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons } } } + BLI_ghashIterator_free(iter); } diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 283b09f42e4..e44cc1f5df3 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -41,7 +41,6 @@ set(SRC transform_generics.c transform_input.c transform_manipulator.c - transform_ndofinput.c transform_ops.c transform_orientations.c transform_snap.c diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 39e26bc6436..b234ac4ceec 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1006,11 +1006,6 @@ int transformEvent(TransInfo *t, wmEvent *event) else view_editmove(event->type); t->redraw= 1; break; -#if 0 - case NDOF_MOTION: - // should have been caught by tranform_modal - return OPERATOR_PASS_THROUGH; -#endif default: handled = 0; break; @@ -1361,16 +1356,15 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) ToolSettings *ts = CTX_data_tool_settings(C); int constraint_axis[3] = {0, 0, 0}; int proportional = 0; + PropertyRNA *prop; - if (RNA_struct_find_property(op->ptr, "value")) - { - if (t->flag & T_AUTOVALUES) - { - RNA_float_set_array(op->ptr, "value", t->auto_values); + if ((prop= RNA_struct_find_property(op->ptr, "value"))) { + float *values= (t->flag & T_AUTOVALUES) ? t->auto_values : t->values; + if (RNA_property_array_check(prop)) { + RNA_property_float_set_array(op->ptr, prop, values); } - else - { - RNA_float_set_array(op->ptr, "value", t->values); + else { + RNA_property_float_set(op->ptr, prop, values[0]); } } @@ -4654,7 +4648,7 @@ static int createSlideVerts(TransInfo *t) uv_new = tf->uv[k]; if (ev->tmp.l) { - if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) { + if (fabsf(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) { ev->tmp.l = -1; /* Tag as invalid */ BLI_linklist_free(suv->fuv_list,NULL); suv->fuv_list = NULL; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index d8e42488787..485344875d4 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -67,14 +67,6 @@ struct wmTimer; struct ARegion; struct ReportList; -typedef struct NDofInput { - int flag; - int axis; - float fval[7]; - float factor[3]; -} NDofInput; - - /* The ctrl value has different meaning: 0 : No value has been typed @@ -273,7 +265,6 @@ typedef struct TransInfo { TransCon con; /* transformed constraint */ TransSnap tsnap; NumInput num; /* numerical input */ - NDofInput ndof; /* ndof input */ MouseInput mouse; /* mouse input */ char redraw; /* redraw flag */ float prop_size; /* proportional circle radius */ @@ -340,9 +331,6 @@ typedef struct TransInfo { /* ******************** Macros & Prototypes *********************** */ -/* NDOFINPUT FLAGS */ -#define NDOF_INIT 1 - /* transinfo->state */ #define TRANS_STARTING 0 #define TRANS_RUNNING 1 @@ -683,20 +671,6 @@ void calculatePropRatio(TransInfo *t); void getViewVector(TransInfo *t, float coord[3], float vec[3]); -/*********************** NDofInput ********************************/ - -void initNDofInput(NDofInput *n); -int hasNDofInput(NDofInput *n); -void applyNDofInput(NDofInput *n, float *vec); -int handleNDofInput(NDofInput *n, struct wmEvent *event); - -/* handleNDofInput return values */ -#define NDOF_REFRESH 1 -#define NDOF_NOMOVE 2 -#define NDOF_CONFIRM 3 -#define NDOF_CANCEL 4 - - /*********************** Transform Orientations ******************************/ void initTransformOrientation(struct bContext *C, TransInfo *t); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c81c398e696..306796efee9 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1165,7 +1165,6 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) setTransformViewMatrices(t); initNumInput(&t->num); - initNDofInput(&t->ndof); return 1; } diff --git a/source/blender/editors/transform/transform_ndofinput.c b/source/blender/editors/transform/transform_ndofinput.c deleted file mode 100644 index c5946163770..00000000000 --- a/source/blender/editors/transform/transform_ndofinput.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is: all of this file. - * - * Contributor(s): Martin Poirier - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/transform/transform_ndofinput.c - * \ingroup edtransform - */ - - - #include <math.h> /* fabs */ -#include <stdio.h> /* for sprintf */ - -#include "BLI_utildefines.h" - -#include "BKE_global.h" /* for G */ - /* ABS */ - -#include "WM_types.h" - -#include "transform.h" - -#if 0 -static int updateNDofMotion(NDofInput *n); // return 0 when motion is null -#endif -static void resetNDofInput(NDofInput *n); - -void initNDofInput(NDofInput *n) -{ - int i; - - n->flag = 0; - n->axis = 0; - - resetNDofInput(n); - - for(i = 0; i < 3; i++) - { - n->factor[i] = 1.0f; - } -} - -static void resetNDofInput(NDofInput *n) -{ - int i; - for(i = 0; i < 6; i++) - { - n->fval[i] = 0.0f; - } -} - - -int handleNDofInput(NDofInput *UNUSED(n), wmEvent *UNUSED(event)) -{ - int retval = 0; - // TRANSFORM_FIX_ME -#if 0 - switch(event) - { - case NDOFMOTION: - if (updateNDofMotion(n) == 0) - { - retval = NDOF_NOMOVE; - } - else - { - retval = NDOF_REFRESH; - } - break; - case NDOFBUTTON: - if (val == 1) - { - retval = NDOF_CONFIRM; - } - else if (val == 2) - { - retval = NDOF_CANCEL; - resetNDofInput(n); - n->flag &= ~NDOF_INIT; - } - break; - } -#endif - return retval; -} - -int hasNDofInput(NDofInput *n) -{ - return (n->flag & NDOF_INIT) == NDOF_INIT; -} - -void applyNDofInput(NDofInput *n, float *vec) -{ - if (hasNDofInput(n)) - { - int i, j; - - for (i = 0, j = 0; i < 6; i++) - { - if (n->axis & (1 << i)) - { - vec[j] = n->fval[i] * n->factor[j]; - j++; - } - } - } -} - -// TRANSFORM_FIX_ME -#if 0 - -static int updateNDofMotion(NDofInput *n) -{ - float fval[7]; - int i; - int retval = 0; - - getndof(fval); - - if (G.vd->ndoffilter) - filterNDOFvalues(fval); - - for(i = 0; i < 6; i++) - { - if (!retval && fval[i] != 0.0f) - { - retval = 1; - } - - n->fval[i] += fval[i] / 1024.0f; - } - - n->flag |= NDOF_INIT; - - return retval; -} -#endif - - - - diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 54e0b31e201..231293024f0 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -360,17 +360,14 @@ static int transform_modal(bContext *C, wmOperator *op, wmEvent *event) TransInfo *t = op->customdata; - #if 0 +#if 0 // stable 2D mouse coords map to different 3D coords while the 3D mouse is active // in other words, 2D deltas are no longer good enough! // disable until individual 'transformers' behave better if (event->type == NDOF_MOTION) - { - /* puts("transform_modal: passing through NDOF_MOTION"); */ return OPERATOR_PASS_THROUGH; - } - #endif +#endif /* XXX insert keys are called here, and require context */ t->context= C; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index ae6836446fa..e8a7896abd5 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -205,11 +205,7 @@ static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short imp float *uv[4]; int nverts; - if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) { - if(efa->h) - continue; - } - else if((efa->h) || (sel && (efa->f & SELECT)==0)) + if((efa->h) || (sel && (efa->f & SELECT)==0)) continue; tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); @@ -586,7 +582,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) return; } - liveHandle = construct_param_handle(scene, em, 0, fillholes, 1, 1); + liveHandle = construct_param_handle(scene, em, 0, fillholes, 0, 1); param_lscm_begin(liveHandle, PARAM_TRUE, abf); BKE_mesh_end_editmesh(obedit->data, em); diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 8bf923a5679..d0c7f9d494f 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -178,6 +178,7 @@ typedef struct GPUVertexAttribs { struct { int type; int glindex; + int gltexco; char name[32]; } layer[GPU_MAX_ATTRIB]; diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 919b0eb0c29..8b0104fcdca 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -355,7 +355,7 @@ struct anim * IMB_open_anim( const char * name, int ib_flags) { anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct"); if (anim != NULL) { - strcpy(anim->name, name); /* fixme: possible buffer overflow here? */ + BLI_strncpy(anim->name, name, sizeof(anim->name)); anim->ib_flags = ib_flags; } return(anim); diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index 1644e653df4..3f391b91c0f 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -371,11 +371,15 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter) float weight[25]; /* build a weights buffer */ - n= 2; - k= 0; + n= 1; + /*k= 0; for(i = -n; i <= n; i++) for(j = -n; j <= n; j++) weight[k++] = sqrt((float) i * i + j * j); + */ + weight[0]=1; weight[1]=2; weight[2]=1; + weight[3]=2; weight[4]=0; weight[5]=2; + weight[6]=1; weight[7]=2; weight[8]=1; /* run passes */ for(r = 0; cannot_early_out == 1 && r < filter; r++) { @@ -393,10 +397,10 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter) float acc[4]={0,0,0,0}; k = 0; - if (check_pixel_assigned(srcbuf, srcmask, filter_make_index(x-1, y, width, height), depth, is_float) || + /*if (check_pixel_assigned(srcbuf, srcmask, filter_make_index(x-1, y, width, height), depth, is_float) || check_pixel_assigned(srcbuf, srcmask, filter_make_index(x+1, y, width, height), depth, is_float) || check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y-1, width, height), depth, is_float) || - check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y+1, width, height), depth, is_float)) { + check_pixel_assigned(srcbuf, srcmask, filter_make_index(x, y+1, width, height), depth, is_float))*/ { for(i= -n; i<=n; i++) { for(j=-n; j<=n; j++) { if(i != 0 || j != 0) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 05730576c4a..9f22a67d11e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -713,16 +713,16 @@ typedef struct ShapeKeyModifierData { typedef struct SolidifyModifierData { ModifierData modifier; - char defgrp_name[32]; /* name of vertex group to use */ + char defgrp_name[32]; /* name of vertex group to use */ float offset; /* new surface offset level*/ float offset_fac; /* midpoint of the offset */ + float offset_fac_vg; /* factor for the minimum weight to use when vgroups are used, avoids 0.0 weights giving duplicate geometry */ float crease_inner; float crease_outer; float crease_rim; int flag; short mat_ofs; short mat_ofs_rim; - int pad; } SolidifyModifierData; #define MOD_SOLIDIFY_RIM (1<<0) diff --git a/source/blender/makesdna/DNA_sdna_types.h b/source/blender/makesdna/DNA_sdna_types.h index e5f924b5fa6..829d1eee03b 100644 --- a/source/blender/makesdna/DNA_sdna_types.h +++ b/source/blender/makesdna/DNA_sdna_types.h @@ -54,7 +54,10 @@ typedef struct SDNA { (sp[2], sp[3]), (sp[4], sp[5]), .. are the member type and name numbers respectively */ - + + struct GHash *structs_map; /* ghash for faster lookups, + requires WITH_DNA_GHASH to be used for now */ + /* wrong place for this really, its a simple * cache for findstruct_nr. */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index aa6da3aaeca..556f554eb98 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -341,7 +341,8 @@ typedef struct UserDef { struct ListBase themes; struct ListBase uifonts; struct ListBase uistyles; - struct ListBase keymaps; + struct ListBase keymaps; /* deprecated in favor of user_keymaps */ + struct ListBase user_keymaps; struct ListBase addons; char keyconfigstr[64]; @@ -602,7 +603,7 @@ extern UserDef U; /* from blenkernel blender.c */ #define NDOF_ORBIT_INVERT_AXES (1 << 6) /* zoom is up/down if this flag is set (otherwise forward/backward) */ #define NDOF_ZOOM_UPDOWN (1 << 7) -#define NDOF_INVERT_ZOOM (1 << 8) +#define NDOF_ZOOM_INVERT (1 << 8) #ifdef __cplusplus diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 31e59f18626..1f0ae28a00d 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -144,7 +144,9 @@ typedef struct wmWindowManager { ListBase drags; /* active dragged items */ ListBase keyconfigs; /* known key configurations */ - struct wmKeyConfig *defaultconf; /* default configuration, not saved */ + struct wmKeyConfig *defaultconf; /* default configuration */ + struct wmKeyConfig *addonconf; /* addon configuration */ + struct wmKeyConfig *userconf; /* user configuration */ ListBase timers; /* active timers */ struct wmTimer *autosavetimer; /* timer for auto save */ @@ -239,15 +241,26 @@ typedef struct wmKeyMapItem { struct PointerRNA *ptr; /* rna pointer to access properties */ } wmKeyMapItem; +/* used instead of wmKeyMapItem for diff keymaps */ +typedef struct wmKeyMapDiffItem { + struct wmKeyMapDiffItem *next, *prev; + + wmKeyMapItem *remove_item; + wmKeyMapItem *add_item; +} wmKeyMapDiffItem; + /* wmKeyMapItem.flag */ -#define KMI_INACTIVE 1 -#define KMI_EXPANDED 2 +#define KMI_INACTIVE 1 +#define KMI_EXPANDED 2 +#define KMI_USER_MODIFIED 4 +#define KMI_UPDATE 8 /* stored in WM, the actively used keymaps */ typedef struct wmKeyMap { struct wmKeyMap *next, *prev; ListBase items; + ListBase diff_items; char idname[64]; /* global editor keymaps, or for more per space/region */ short spaceid; /* same IDs as in DNA_space_types.h */ @@ -263,9 +276,12 @@ typedef struct wmKeyMap { /* wmKeyMap.flag */ #define KEYMAP_MODAL 1 /* modal map, not using operatornames */ -#define KEYMAP_USER 2 /* user created keymap */ +#define KEYMAP_USER 2 /* user keymap */ #define KEYMAP_EXPANDED 4 #define KEYMAP_CHILDREN_EXPANDED 8 +#define KEYMAP_DIFF 16 /* diff keymap for user preferences */ +#define KEYMAP_USER_MODIFIED 32 /* keymap has user modifications */ +#define KEYMAP_UPDATE 64 typedef struct wmKeyConfig { struct wmKeyConfig *next, *prev; diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 429db63b526..5edebfe3903 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -27,12 +27,17 @@ # message(STATUS "Configuring makesdna") +# add_definitions(-DWITH_DNA_GHASH) + blender_include_dirs( ../../../../intern/guardedalloc ../../blenloader + ../../blenlib .. ) + +# ----------------------------------------------------------------------------- # Build makesdna executable set(SRC makesdna.c @@ -56,6 +61,8 @@ add_custom_command( DEPENDS makesdna ) + +# ----------------------------------------------------------------------------- # Build bf_dna library set(INC @@ -72,3 +79,22 @@ set(SRC ) blender_add_lib(bf_dna "${SRC}" "${INC}" "${INC_SYS}") + + +# ----------------------------------------------------------------------------- +# Build bf_dna_blenlib library +set(INC + +) + +set(INC_SYS + +) + +set(SRC + ../../blenlib/intern/BLI_mempool.c + ../../blenlib/intern/listbase.c + ../../blenlib/intern/BLI_ghash.c +) + +blender_add_lib(bf_dna_blenlib "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index e51ee53e078..8185676cbfc 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/SConscript @@ -67,5 +67,6 @@ else: else: dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET") +# TODO, get WITH_DNA_GHASH working, see CMake's 'WITH_DNA_GHASH' obj = ['intern/dna.c', 'intern/dna_genfile.c'] Return ('obj') diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 4e9b023b326..ebcfce84e37 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -42,6 +42,10 @@ #include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN +#ifdef WITH_DNA_GHASH +# include "BLI_ghash.h" +#endif + #include "DNA_genfile.h" #include "DNA_sdna_types.h" // for SDNA ;-) @@ -197,7 +201,11 @@ void DNA_sdna_free(SDNA *sdna) MEM_freeN((void *)sdna->names); MEM_freeN(sdna->types); MEM_freeN(sdna->structs); - + +#ifdef WITH_DNA_GHASH + BLI_ghash_free(sdna->structs_map, NULL, NULL); +#endif + MEM_freeN(sdna); } @@ -275,24 +283,30 @@ static short *findstruct_name(SDNA *sdna, const char *str) int DNA_struct_find_nr(SDNA *sdna, const char *str) { short *sp= NULL; - int a; if(sdna->lastfind<sdna->nr_structs) { sp= sdna->structs[sdna->lastfind]; if(strcmp( sdna->types[ sp[0] ], str )==0) return sdna->lastfind; } - for(a=0; a<sdna->nr_structs; a++) { +#ifdef WITH_DNA_GHASH + return (intptr_t)BLI_ghash_lookup(sdna->structs_map, str) - 1; +#else + { + int a; - sp= sdna->structs[a]; - - if(strcmp( sdna->types[ sp[0] ], str )==0) { - sdna->lastfind= a; - return a; + for(a=0; a<sdna->nr_structs; a++) { + + sp= sdna->structs[a]; + + if(strcmp( sdna->types[ sp[0] ], str )==0) { + sdna->lastfind= a; + return a; + } } } - return -1; +#endif } /* ************************* END DIV ********************** */ @@ -481,6 +495,16 @@ static void init_structDNA(SDNA *sdna, int do_endian_swap) sp[10]= 9; } } + +#ifdef WITH_DNA_GHASH + /* create a ghash lookup to speed up */ + sdna->structs_map= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "init_structDNA gh"); + + for(nr = 0; nr < sdna->nr_structs; nr++) { + sp= sdna->structs[nr]; + BLI_ghash_insert(sdna->structs_map, (void *)sdna->types[sp[0]], (void *)(nr + 1)); + } +#endif } } diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index e617ec5c45a..512249a3b3f 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -396,6 +396,7 @@ extern StructRNA RNA_Scene; extern StructRNA RNA_SceneGameData; extern StructRNA RNA_SceneRenderLayer; extern StructRNA RNA_SceneSequence; +extern StructRNA RNA_SceneObjects; extern StructRNA RNA_Scopes; extern StructRNA RNA_Screen; extern StructRNA RNA_ScrewModifier; @@ -657,7 +658,7 @@ int RNA_property_flag(PropertyRNA *prop); void *RNA_property_py_data_get(PropertyRNA *prop); int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop); -int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop); +int RNA_property_array_check(PropertyRNA *prop); int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension); int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]); char RNA_property_array_item_char(PropertyRNA *prop, int index); diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index ec213d6a496..f8199074f27 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -281,7 +281,7 @@ typedef struct ParameterList { typedef struct ParameterIterator { struct ParameterList *parms; - PointerRNA funcptr; + /* PointerRNA funcptr; */ /*UNUSED*/ void *data; int size, offset; diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index b706db5e64c..1cb24630fbe 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -54,7 +54,7 @@ if env['WITH_BF_PYTHON']: if env['WITH_BF_COLLADA']: defs.append('WITH_COLLADA') -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 3903ac8be4c..63ae4f5f81f 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -244,6 +244,7 @@ blender_include_dirs_sys( add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC}) target_link_libraries(makesrna bf_dna) +target_link_libraries(makesrna bf_dna_blenlib) # Output rna_*_gen.c # note (linux only): with crashes try add this after COMMAND: valgrind --leak-check=full --track-origins=yes diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index 5e43ed9b2fb..24c892b96c4 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -91,7 +91,7 @@ if env['WITH_BF_PYTHON']: if env['WITH_BF_COLLADA']: defs.append('WITH_COLLADA') -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' @@ -140,7 +140,7 @@ targetpath = root_build_dir+'/makesrna' if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): targetpath = '#' + targetpath -if env['OURPLATFORM'] == 'linux2' and root_build_dir[0]==os.sep: +if env['OURPLATFORM'] == 'linux' and root_build_dir[0]==os.sep: makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_intern_guardedalloc', 'bf_dna', 'bf_blenlib']) else: makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_intern_guardedalloc', 'bf_dna', 'bf_blenlib']) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index f1056c86a4c..88447f6dd77 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -288,7 +288,7 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop) } } -static int rna_ensure_property_array_check(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static int rna_ensure_property_array_check(PropertyRNA *prop) { if(prop->magic == RNA_MAGIC) { return (prop->getlength || prop->totarraylength) ? 1:0; @@ -765,9 +765,9 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop) return rna_ensure_property_array_length(ptr, prop); } -int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop) +int RNA_property_array_check(PropertyRNA *prop) { - return rna_ensure_property_array_check(ptr, prop); + return rna_ensure_property_array_check(prop); } /* used by BPY to make an array from the python object */ @@ -1399,6 +1399,7 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) == 0); if((idprop=rna_idproperty_check(&prop, ptr))) return IDP_Int(idprop); @@ -1414,6 +1415,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) == 0); /* just incase other values are passed */ if(value) value= 1; @@ -1440,6 +1442,7 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) @@ -1463,6 +1466,7 @@ int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_boolean_get_array(ptr, prop, tmp); @@ -1486,6 +1490,7 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) @@ -1519,6 +1524,7 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_boolean_get_array(ptr, prop, tmp); @@ -1541,6 +1547,7 @@ int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop) BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) == 0); return bprop->defaultvalue; } @@ -1550,6 +1557,7 @@ void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop; BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if(prop->arraydimension == 0) values[0]= bprop->defaultvalue; @@ -1565,6 +1573,7 @@ int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_boolean_get_default_array(ptr, prop, tmp); @@ -1588,6 +1597,7 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) == 0); if((idprop=rna_idproperty_check(&prop, ptr))) return IDP_Int(idprop); @@ -1603,6 +1613,7 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) == 0); /* useful to check on bad values but set function should clamp */ /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */ @@ -1628,6 +1639,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) @@ -1688,6 +1700,7 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index) int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_int_get_array(ptr, prop, tmp); @@ -1711,6 +1724,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) @@ -1744,6 +1758,7 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_int_get_array(ptr, prop, tmp); @@ -1772,6 +1787,7 @@ void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *pr IntPropertyRNA *iprop= (IntPropertyRNA*)prop; BLI_assert(RNA_property_type(prop) == PROP_INT); + BLI_assert(RNA_property_array_check(prop) != 0); if(prop->arraydimension == 0) values[0]= iprop->defaultvalue; @@ -1808,6 +1824,7 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) == 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(idprop->type == IDP_FLOAT) @@ -1827,6 +1844,7 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value) IDProperty *idprop; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) == 0); /* useful to check on bad values but set function should clamp */ /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */ @@ -1858,6 +1876,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val int i; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) @@ -1923,6 +1942,7 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_float_get_array(ptr, prop, tmp); @@ -1948,6 +1968,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa int i; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if((idprop=rna_idproperty_check(&prop, ptr))) { if(prop->arraydimension == 0) { @@ -1991,6 +2012,7 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_float_get_array(ptr, prop, tmp); @@ -2013,6 +2035,7 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop) FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) == 0); return fprop->defaultvalue; } @@ -2022,6 +2045,7 @@ void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA * FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if(prop->arraydimension == 0) values[0]= fprop->defaultvalue; @@ -2037,6 +2061,7 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i int len= rna_ensure_property_array_length(ptr, prop); BLI_assert(RNA_property_type(prop) == PROP_FLOAT); + BLI_assert(RNA_property_array_check(prop) != 0); if(len <= RNA_MAX_ARRAY_LENGTH) { RNA_property_float_get_default_array(ptr, prop, tmp); @@ -4484,7 +4509,8 @@ int RNA_parameter_list_ret_count(ParameterList *parms) void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter) { - RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr); + /* may be useful but unused now */ + /* RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr); */ /*UNUSED*/ iter->parms= parms; iter->parm= parms->func->cont.properties.first; diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 1ce4108bab2..1b2396a4215 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -294,6 +294,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL); RNA_def_property_ui_text(prop, "Pin Cloth", "Enable pinning of cloth vertices to other objects/positions"); RNA_def_property_update(prop, 0, "rna_cloth_pinning_changed"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop= RNA_def_property(srna, "pin_stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "goalspring"); @@ -313,6 +314,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SCALING); RNA_def_property_ui_text(prop, "Stiffness Scaling", "If enabled, stiffness can be scaled along a weight painted vertex group"); RNA_def_property_update(prop, 0, "rna_cloth_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop= RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "Cdis"); diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 0163dd5db32..8127c180706 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -85,7 +85,7 @@ static EnumPropertyItem target_space_pchan_items[] = { static EnumPropertyItem owner_space_pchan_items[] = { {0, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"}, {2, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"}, - {3, "LOCAL_WITH_PARENT", 0, "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"}, + {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"}, {1, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 260d483b9d2..599d36ec8b8 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -651,7 +651,7 @@ static char *rna_TextBox_path(PointerRNA *ptr) int index= (int)(tb - cu->tb); if (index >= 0 && index < cu->totbox) - return BLI_sprintfN("textboxes[%d]", index); + return BLI_sprintfN("text_boxes[%d]", index); else return BLI_strdup(""); } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 805f9639ab1..ba36fcbc94f 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -239,9 +239,12 @@ void RNA_api_image(struct StructRNA *srna); void RNA_api_operator(struct StructRNA *srna); void RNA_api_macro(struct StructRNA *srna); void RNA_api_keyconfig(struct StructRNA *srna); +void RNA_api_keyconfigs(struct StructRNA *srna); void RNA_api_keyingset(struct StructRNA *srna); void RNA_api_keymap(struct StructRNA *srna); +void RNA_api_keymaps(struct StructRNA *srna); void RNA_api_keymapitem(struct StructRNA *srna); +void RNA_api_keymapitems(struct StructRNA *srna); void RNA_api_area(struct StructRNA *srna); void RNA_api_main(struct StructRNA *srna); void RNA_api_material(StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 3571ff3c266..b9d49901ee5 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2295,6 +2295,13 @@ static void rna_def_modifier_solidify(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Thickness", "Thickness of the shell"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop= RNA_def_property(srna, "thickness_vertex_group", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "offset_fac_vg"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0, 1, 0.1, 3); + RNA_def_property_ui_text(prop, "Vertex Group Factor", "Thickness factor to use for zero vertex group influence"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "offset_fac"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 76bbfcbed41..55e1119f58e 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2025,7 +2025,14 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Input Matrix", "Matrix access to location, rotation and scale (including deltas), before constraints and parenting are applied."); RNA_def_property_float_funcs(prop, "rna_Object_matrix_basis_get", "rna_Object_matrix_basis_set", NULL); RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - + + /*parent_inverse*/ + prop= RNA_def_property(srna, "matrix_parent_inverse", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "parentinv"); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(prop, "Matrix", "Inverse of object's parent matrix at time of parenting"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); + /* collections */ prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Constraint"); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 2a4ea815260..61ebe216b53 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -786,7 +786,6 @@ static void rna_def_pointcache(BlenderRNA *brna) prop= RNA_def_property(srna, "compression", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, point_cache_compress_items); RNA_def_property_ui_text(prop, "Cache Compression", "Compression method to be used"); - RNA_def_property_update(prop, 0, NULL); /* flags */ prop= RNA_def_property(srna, "is_baked", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b3d8bc8ea18..29cfc695911 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1409,7 +1409,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) prop= RNA_def_property(srna, "layers_zmask", PROP_BOOLEAN, PROP_LAYER); RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1); RNA_def_property_array(prop, 20); - RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers"); + RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers for solid faces"); if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c index 5cc8539f187..1f64603d6b4 100644 --- a/source/blender/makesrna/intern/rna_sensor.c +++ b/source/blender/makesrna/intern/rna_sensor.c @@ -803,7 +803,7 @@ static void rna_def_joystick_sensor(BlenderRNA *brna) prop= RNA_def_property(srna, "axis_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "axis"); RNA_def_property_ui_text(prop, "Axis Number", "Specify which axis pair to use, 1 is usually the main direction input"); - RNA_def_property_range(prop, 1, 2); + RNA_def_property_range(prop, 1, 8); RNA_def_property_update(prop, NC_LOGIC, NULL); prop= RNA_def_property(srna, "axis_threshold", PROP_INT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 8c4e4d9e736..476ac325848 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1481,7 +1481,7 @@ static void rna_def_wipe(BlenderRNA *brna) #if 1 /* expose as radians */ prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_funcs(prop, "rna_WipeSequence_angle_get", "rna_WipeSequence_angle_set", NULL); - RNA_def_property_range(prop, DEG2RAD(-90.0f), DEG2RAD(90.0f)); + RNA_def_property_range(prop, DEG2RAD(-90.0), DEG2RAD(90.0)); #else prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "angle"); diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 43d1aa24229..d439c2551f1 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -241,13 +241,12 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "cache_comp"); RNA_def_property_enum_items(prop, smoke_cache_comp_items); RNA_def_property_ui_text(prop, "Cache Compression", "Compression method to be used"); - RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "collision_extents", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "border_collisions"); RNA_def_property_enum_items(prop, smoke_domain_colli_items); RNA_def_property_ui_text(prop, "Border Collisions", "Selects which domain border will be treated as collision object."); - RNA_def_property_update(prop, 0, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset"); prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "EffectorWeights"); @@ -290,14 +289,12 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.001, 1); RNA_def_property_ui_range(prop, 0.001, 1.0, 1.0, 4); RNA_def_property_ui_text(prop, "Density", ""); - RNA_def_property_update(prop, 0, NULL); // NC_OBJECT|ND_MODIFIER prop= RNA_def_property(srna, "temperature", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "temp"); RNA_def_property_range(prop, -10, 10); RNA_def_property_ui_range(prop, -10, 10, 1, 1); RNA_def_property_ui_text(prop, "Temp. Diff.", "Temperature difference to ambient temperature"); - RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "psys"); @@ -309,24 +306,20 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "use_outflow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW); RNA_def_property_ui_text(prop, "Outflow", "Deletes smoke from simulation"); - RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "use_absolute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_ABSOLUTE); RNA_def_property_ui_text(prop, "Absolute Density", "Only allows given density value in emitter area."); - RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_INITVELOCITY); RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits it's velocity from the emitter particle"); - RNA_def_property_update(prop, 0, NULL); prop= RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vel_multi"); RNA_def_property_range(prop, -2.0, 2.0); RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); RNA_def_property_ui_text(prop, "Multiplier", "Multiplier to adjust velocity passed to smoke"); - RNA_def_property_update(prop, 0, NULL); } static void rna_def_smoke_coll_settings(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a1a99c34e70..a685c6deb34 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2746,19 +2746,32 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Drag Threshold", "Amount of pixels you have to drag before dragging UI items happens"); /* 3D mouse settings */ + /* global options */ prop= RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.25f, 4.0f); RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse"); + prop= RNA_def_property(srna, "ndof_zoom_updown", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_UPDOWN); + RNA_def_property_ui_text(prop, "Zoom = Up/Down", "Zoom using up/down on the device (otherwise forward/backward)"); + + prop= RNA_def_property(srna, "ndof_zoom_invert", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_INVERT); + RNA_def_property_ui_text(prop, "Invert Zoom", "Zoom using opposite direction"); + + /* 3D view */ prop= RNA_def_property(srna, "ndof_show_guide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_SHOW_GUIDE); RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation"); /* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/ + /* 3D view: orbit */ prop= RNA_def_property(srna, "ndof_orbit_invert_axes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ORBIT_INVERT_AXES); RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed"); + /* in 3Dx docs, this is called 'object mode' vs. 'target camera mode' */ + /* 3D view: fly */ prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON); RNA_def_property_ui_text(prop, "Lock Horizon", "Keep horizon level while flying with 3D Mouse"); @@ -2795,12 +2808,6 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_range(prop, 0, 32); RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "The number of lines scrolled at a time with the mouse wheel"); - /* U.keymaps - custom keymaps that have been edited from default configs */ - prop= RNA_def_property(srna, "edited_keymaps", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "keymaps", NULL); - RNA_def_property_struct_type(prop, "KeyMap"); - RNA_def_property_ui_text(prop, "Edited Keymaps", ""); - prop= RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH); RNA_def_property_string_sdna(prop, NULL, "keyconfigstr"); RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index a046be59ab5..93adf808f83 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -578,22 +578,6 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA wmKeyConfig *kc; wmKeyMap *km; - /* check user keymaps */ - for(km=U.keymaps.first; km; km=km->next) { - wmKeyMapItem *kmi; - for (kmi=km->items.first; kmi; kmi=kmi->next) { - if (kmi == ptr->data) { - if (!km->modal_items) { - if (!WM_keymap_user_init(wm, km)) { - return keymap_propvalue_items; /* ERROR */ - } - } - - return km->modal_items; - } - } - } - for(kc=wm->keyconfigs.first; kc; kc=kc->next) { for(km=kc->keymaps.first; km; km=km->next) { /* only check if it's a modal keymap */ @@ -654,12 +638,13 @@ static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc); } -static void rna_WindowManager_active_keyconfig_set(PointerRNA *UNUSED(ptr), PointerRNA value) +static void rna_WindowManager_active_keyconfig_set(PointerRNA *ptr, PointerRNA value) { + wmWindowManager *wm= ptr->data; wmKeyConfig *kc= value.data; if(kc) - BLI_strncpy(U.keyconfigstr, kc->idname, sizeof(U.keyconfigstr)); + WM_keyconfig_set_active(wm, kc->idname); } static void rna_wmKeyMapItem_idname_get(PointerRNA *ptr, char *value) @@ -1130,93 +1115,6 @@ static StructRNA* rna_MacroOperator_refine(PointerRNA *opr) return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro; } -static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) -{ -// wmWindowManager *wm = CTX_wm_manager(C); - char idname_bl[OP_MAX_TYPENAME]; - int modifier= 0; - - /* only on non-modal maps */ - if (km->flag & KEYMAP_MODAL) { - BKE_report(reports, RPT_ERROR, "Not a non-modal keymap."); - return NULL; - } - - WM_operator_bl_idname(idname_bl, idname); - - if(shift) modifier |= KM_SHIFT; - if(ctrl) modifier |= KM_CTRL; - if(alt) modifier |= KM_ALT; - if(oskey) modifier |= KM_OSKEY; - - if(any) modifier = KM_ANY; - - return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier); -} - -static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, bContext *C, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) -{ - wmWindowManager *wm = CTX_wm_manager(C); - int modifier= 0; - int propvalue = 0; - - /* only modal maps */ - if ((km->flag & KEYMAP_MODAL) == 0) { - BKE_report(reports, RPT_ERROR, "Not a modal keymap."); - return NULL; - } - - if (!km->modal_items) { - if(!WM_keymap_user_init(wm, km)) { - BKE_report(reports, RPT_ERROR, "User defined keymap doesn't correspond to a system keymap."); - return NULL; - } - } - - if (!km->modal_items) { - BKE_report(reports, RPT_ERROR, "No property values defined."); - return NULL; - } - - - if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) { - BKE_report(reports, RPT_WARNING, "Property value not in enumeration."); - } - - if(shift) modifier |= KM_SHIFT; - if(ctrl) modifier |= KM_CTRL; - if(alt) modifier |= KM_ALT; - if(oskey) modifier |= KM_OSKEY; - - if(any) modifier = KM_ANY; - - return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); -} - -static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal) -{ - if (modal == 0) { - return WM_keymap_find(keyconf, idname, spaceid, regionid); - } else { - return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */ - } -} - -static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid) -{ - return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); -} - -static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname) -{ - wmOperatorType *ot = WM_operatortype_find(idname, 0); - - if (!ot) - return NULL; - else - return ot->modalkeymap; -} - /* just to work around 'const char *' warning and to ensure this is a python op */ static void rna_Operator_bl_idname_set(PointerRNA *ptr, const char *value) { @@ -1242,6 +1140,12 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value) else assert(!"setting the bl_description on a non-builtin operator"); } +static void rna_KeyMapItem_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + wmKeyMapItem *kmi= ptr->data; + WM_keyconfig_update_tag(NULL, kmi); +} + #else /* RNA_RUNTIME */ static void rna_def_operator(BlenderRNA *brna) @@ -1566,9 +1470,6 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; PropertyRNA *prop; - FunctionRNA *func; - PropertyRNA *parm; - RNA_def_property_srna(cprop, "KeyConfigurations"); srna= RNA_def_struct(brna, "KeyConfigurations", NULL); RNA_def_struct_sdna(srna, "wmWindowManager"); @@ -1578,23 +1479,24 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_struct_type(prop, "KeyConfig"); RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keyconfig_get", "rna_WindowManager_active_keyconfig_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active KeyConfig", "Active wm KeyConfig"); + RNA_def_property_ui_text(prop, "Active KeyConfig", "Active key configuration (preset)"); prop= RNA_def_property(srna, "default", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "defaultconf"); RNA_def_property_struct_type(prop, "KeyConfig"); - RNA_def_property_ui_text(prop, "Default Key Configuration", ""); + RNA_def_property_ui_text(prop, "Default Key Configuration", "Default builtin key configuration"); + + prop= RNA_def_property(srna, "addon", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "addonconf"); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "Addon Key Configuration", "Key configuration that can be extended by addons, and is added to the active configuration when handling events"); + + prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "userconf"); + RNA_def_property_struct_type(prop, "KeyConfig"); + RNA_def_property_ui_text(prop, "User Key Configuration", "Final key configuration that combines keymaps from the active and addon configurations, and can be edited by the user"); - /* funcs */ - func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig - parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration."); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_api_keyconfigs(srna); } static void rna_def_windowmanager(BlenderRNA *brna) @@ -1631,107 +1533,30 @@ static void rna_def_windowmanager(BlenderRNA *brna) static void rna_def_keymap_items(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; -// PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; RNA_def_property_srna(cprop, "KeyMapItems"); srna= RNA_def_struct(brna, "KeyMapItems", NULL); RNA_def_struct_sdna(srna, "wmKeyMap"); RNA_def_struct_ui_text(srna, "KeyMap Items", "Collection of keymap items"); - func= RNA_def_function(srna, "new", "rna_KeyMap_item_new"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "any", 0, "Any", ""); - RNA_def_boolean(func, "shift", 0, "Shift", ""); - RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); - RNA_def_boolean(func, "alt", 0, "Alt", ""); - RNA_def_boolean(func, "oskey", 0, "OS Key", ""); - RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS); - parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_boolean(func, "any", 0, "Any", ""); - RNA_def_boolean(func, "shift", 0, "Shift", ""); - RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); - RNA_def_boolean(func, "alt", 0, "Alt", ""); - RNA_def_boolean(func, "oskey", 0, "OS Key", ""); - RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "remove", "WM_keymap_remove_item"); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - - func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id"); - parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_property_ui_text(parm, "id", "ID of the item"); - parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); - RNA_def_function_return(func, parm); - + RNA_api_keymapitems(srna); } static void rna_def_wm_keymaps(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; - //PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - RNA_def_property_srna(cprop, "KeyMaps"); srna= RNA_def_struct(brna, "KeyMaps", NULL); RNA_def_struct_sdna(srna, "wmKeyConfig"); RNA_def_struct_ui_text(srna, "Key Maps", "Collection of keymaps"); - func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); - RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); - RNA_def_boolean(func, "modal", 0, "Modal", ""); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap - parm= RNA_def_string(func, "name", "", 0, "Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); - RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal - parm= RNA_def_string(func, "name", "", 0, "Operator Name", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); - RNA_def_function_return(func, parm); - + RNA_api_keymaps(srna); } static void rna_def_keyconfig(BlenderRNA *brna) { StructRNA *srna; - // FunctionRNA *func; - // PropertyRNA *parm; PropertyRNA *prop; static EnumPropertyItem map_type_items[] = { @@ -1794,8 +1619,8 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Items", "Items in the keymap, linking an operator to an input event"); rna_def_keymap_items(brna, prop); - prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NEVER_NULL); - RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER); + prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NEVER_NULL); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER_MODIFIED); RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user"); prop= RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE); @@ -1826,6 +1651,7 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Identifier", "Identifier of operator to call on input event"); RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_idname_get", "rna_wmKeyMapItem_idname_length", "rna_wmKeyMapItem_idname_set"); RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1836,62 +1662,73 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_struct_type(prop, "OperatorProperties"); RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Properties", "Properties to set when the operator is called"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "map_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "maptype"); RNA_def_property_enum_items(prop, map_type_items); RNA_def_property_enum_funcs(prop, "rna_wmKeyMapItem_map_type_get", "rna_wmKeyMapItem_map_type_set", NULL); RNA_def_property_ui_text(prop, "Map Type", "Type of event mapping"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); RNA_def_property_enum_items(prop, event_type_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_type_itemf"); RNA_def_property_ui_text(prop, "Type", "Type of event"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "val"); RNA_def_property_enum_items(prop, event_value_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf"); RNA_def_property_ui_text(prop, "Value", ""); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "id", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "id"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "id", "ID of the item"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "any", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_getf", "rna_KeyMapItem_any_setf"); RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shift", 0); // RNA_def_property_enum_sdna(prop, NULL, "shift"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Shift", "Shift key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0); // RNA_def_property_enum_sdna(prop, NULL, "ctrl"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "alt", 0); // RNA_def_property_enum_sdna(prop, NULL, "alt"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Alt", "Alt key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0); // RNA_def_property_enum_sdna(prop, NULL, "oskey"); // RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "keymodifier"); RNA_def_property_enum_items(prop, event_type_items); RNA_def_property_ui_text(prop, "Key Modifier", "Regular key pressed as a modifier"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_EXPANDED); @@ -1903,15 +1740,22 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_enum_items(prop, keymap_propvalue_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_propvalue_itemf"); RNA_def_property_ui_text(prop, "Property Value", "The value this event translates to in a modal keymap"); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE); RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item"); RNA_def_property_ui_icon(prop, ICON_CHECKBOX_DEHLT, 1); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); + + prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_USER_MODIFIED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "User Modified", "Is this keymap item modified by the user"); prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just override a builtin item)"); + RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just replace a builtin item)"); RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_userdefined_get", NULL); RNA_api_keymapitem(srna); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index d44b68950f7..89e946f498a 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -84,6 +84,85 @@ void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer) WM_event_remove_timer(wm, timer->win, timer); } +static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) +{ +// wmWindowManager *wm = CTX_wm_manager(C); + char idname_bl[OP_MAX_TYPENAME]; + int modifier= 0; + + /* only on non-modal maps */ + if (km->flag & KEYMAP_MODAL) { + BKE_report(reports, RPT_ERROR, "Not a non-modal keymap."); + return NULL; + } + + WM_operator_bl_idname(idname_bl, idname); + + if(shift) modifier |= KM_SHIFT; + if(ctrl) modifier |= KM_CTRL; + if(alt) modifier |= KM_ALT; + if(oskey) modifier |= KM_OSKEY; + + if(any) modifier = KM_ANY; + + return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier); +} + +static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier) +{ + int modifier= 0; + int propvalue = 0; + + /* only modal maps */ + if ((km->flag & KEYMAP_MODAL) == 0) { + BKE_report(reports, RPT_ERROR, "Not a modal keymap."); + return NULL; + } + + if (!km->modal_items) { + BKE_report(reports, RPT_ERROR, "No property values defined."); + return NULL; + } + + + if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) { + BKE_report(reports, RPT_WARNING, "Property value not in enumeration."); + } + + if(shift) modifier |= KM_SHIFT; + if(ctrl) modifier |= KM_CTRL; + if(alt) modifier |= KM_ALT; + if(oskey) modifier |= KM_OSKEY; + + if(any) modifier = KM_ANY; + + return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); +} + +static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal) +{ + if (modal == 0) { + return WM_keymap_find(keyconf, idname, spaceid, regionid); + } else { + return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */ + } +} + +static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid) +{ + return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); +} + +static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname) +{ + wmOperatorType *ot = WM_operatortype_find(idname, 0); + + if (!ot) + return NULL; + else + return ot->modalkeymap; +} + #else #define WM_GEN_INVOKE_EVENT (1<<0) @@ -301,11 +380,8 @@ void RNA_api_keymap(StructRNA *srna) parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Active key map."); RNA_def_function_return(func, parm); - func= RNA_def_function(srna, "copy_to_user", "WM_keymap_copy_to_user"); - parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "User editable key map."); - RNA_def_function_return(func, parm); - - RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default"); + func= RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); func= RNA_def_function(srna, "restore_item_to_default", "rna_keymap_restore_item_to_default"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); @@ -324,5 +400,102 @@ void RNA_api_keymapitem(StructRNA *srna) parm= RNA_def_boolean(func, "result", 0, "Comparison result", ""); RNA_def_function_return(func, parm); } + +void RNA_api_keymapitems(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "rna_KeyMap_item_new"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "any", 0, "Any", ""); + RNA_def_boolean(func, "shift", 0, "Shift", ""); + RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); + RNA_def_boolean(func, "alt", 0, "Alt", ""); + RNA_def_boolean(func, "oskey", 0, "OS Key", ""); + RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_boolean(func, "any", 0, "Any", ""); + RNA_def_boolean(func, "shift", 0, "Shift", ""); + RNA_def_boolean(func, "ctrl", 0, "Ctrl", ""); + RNA_def_boolean(func, "alt", 0, "Alt", ""); + RNA_def_boolean(func, "oskey", 0, "OS Key", ""); + RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", ""); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove", "WM_keymap_remove_item"); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id"); + parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_ui_text(parm, "id", "ID of the item"); + parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); + RNA_def_function_return(func, parm); +} + +void RNA_api_keymaps(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); + RNA_def_boolean(func, "modal", 0, "Modal", ""); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", ""); + RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", ""); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal + parm= RNA_def_string(func, "name", "", 0, "Operator Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map."); + RNA_def_function_return(func, parm); +} + +void RNA_api_keyconfigs(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig + parm= RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration."); + RNA_def_function_return(func, parm); + + func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig + parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration."); + RNA_def_property_flag(parm, PROP_REQUIRED); +} + #endif diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index a0ee047e319..0b46d950950 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -213,4 +213,5 @@ ModifierTypeInfo modifierType_Armature = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 90954fef1c7..c7fa75478f0 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -826,4 +826,5 @@ ModifierTypeInfo modifierType_Array = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 323ed71dd74..277f404f64d 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -150,4 +150,5 @@ ModifierTypeInfo modifierType_Bevel = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 4b4d0124aae..761f8dd0add 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -197,4 +197,5 @@ ModifierTypeInfo modifierType_Boolean = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index e293be5886d..1c56d81a798 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -299,5 +299,6 @@ ModifierTypeInfo modifierType_Build = { /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, - /* foreachIDLink */ NULL + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 14b23ba4972..4061128b5ad 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -632,4 +632,5 @@ ModifierTypeInfo modifierType_Cast = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 1d2a6b2f788..f5493162322 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -229,4 +229,5 @@ ModifierTypeInfo modifierType_Cloth = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 83ba8a12163..f4a9ea62ead 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -267,4 +267,5 @@ ModifierTypeInfo modifierType_Collision = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index ecd10250c00..d928c239eac 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -162,4 +162,5 @@ ModifierTypeInfo modifierType_Curve = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index ba9dbfc31ad..e3c39752bd1 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -218,4 +218,5 @@ ModifierTypeInfo modifierType_Decimate = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index e0482e6b3fc..fb7aeacecc8 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -134,6 +134,12 @@ static void foreachIDLink(ModifierData *md, Object *ob, foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } +static void foreachTexLink(ModifierData *md, Object *ob, + TexWalkFunc walk, void *userData) +{ + walk(userData, ob, md, "texture"); +} + static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) { DisplaceModifierData *dmd = (DisplaceModifierData*) md; @@ -283,4 +289,5 @@ ModifierTypeInfo modifierType_Displace = { /* dependsOnNormals */ dependsOnNormals, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ foreachTexLink, }; diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 8d0aea41b5c..db491742265 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -1311,4 +1311,5 @@ ModifierTypeInfo modifierType_EdgeSplit = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 5da2464ef89..3d01661bc79 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1037,4 +1037,5 @@ ModifierTypeInfo modifierType_Explode = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c index 354dc33ffe0..cce288b4ad5 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim.c +++ b/source/blender/modifiers/intern/MOD_fluidsim.c @@ -162,4 +162,5 @@ ModifierTypeInfo modifierType_Fluidsim = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index ea8d602dd7a..785abc7d4d1 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -289,4 +289,5 @@ ModifierTypeInfo modifierType_Hook = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 694f8fb3e52..31c17fb7376 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -156,4 +156,5 @@ ModifierTypeInfo modifierType_Lattice = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 94442d96367..b7cdac9e246 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -407,4 +407,5 @@ ModifierTypeInfo modifierType_Mask = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 3903f2602e4..8a0e64e7ee4 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -463,4 +463,5 @@ ModifierTypeInfo modifierType_MeshDeform = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index b1c765e5c9b..7cde87b20d9 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -363,4 +363,5 @@ ModifierTypeInfo modifierType_Mirror = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 134574ae6c4..48b1112cad2 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -131,4 +131,5 @@ ModifierTypeInfo modifierType_Multires = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c index 48c5b9a4c08..8fed2150a75 100644 --- a/source/blender/modifiers/intern/MOD_none.c +++ b/source/blender/modifiers/intern/MOD_none.c @@ -77,4 +77,5 @@ ModifierTypeInfo modifierType_None = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 46d53e0db15..b0b43e018f7 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -350,4 +350,5 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 533bfd203b5..5635ba33d80 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -242,4 +242,5 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 17e350482f0..c5fdf465a0a 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -903,4 +903,5 @@ ModifierTypeInfo modifierType_Screw = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 94d23de6573..6e55466c1e4 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -148,5 +148,6 @@ ModifierTypeInfo modifierType_ShapeKey = { /* dependsOnTime */ NULL, /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, - /* foreachIDLink */ NULL + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index e1fc4bc969f..ba25df19b3e 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -186,4 +186,5 @@ ModifierTypeInfo modifierType_Shrinkwrap = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 5efd6cd28ec..b2e3c9532b6 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -385,4 +385,5 @@ ModifierTypeInfo modifierType_SimpleDeform = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index b6203bb3c1d..2e156d82ec6 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -189,4 +189,5 @@ ModifierTypeInfo modifierType_Smoke = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ NULL }; diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 28a31b84ea5..16898a80b53 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -270,4 +270,5 @@ ModifierTypeInfo modifierType_Smooth = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 25996286735..c475328676b 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -87,4 +87,5 @@ ModifierTypeInfo modifierType_Softbody = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 390a780e9e6..afe6da8b38a 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -232,8 +232,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, float (*vert_nors)[3]= NULL; - float const ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); - float const ofs_new= smd->offset - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + const float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + const float ofs_new= smd->offset - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + const float offset_fac_vg= smd->offset_fac_vg; + const float offset_fac_vg_inv= 1.0f - smd->offset_fac_vg; /* weights */ MDeformVert *dvert, *dv= NULL; @@ -391,8 +393,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, dv= dvert; for(i=0; i<numVerts; i++, mv++) { if(dv) { - if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); - else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + if(defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); + else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup= (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; dv++; } VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); @@ -405,8 +408,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, dv= dvert; for(i=0; i<numVerts; i++, mv++) { if(dv) { - if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); - else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + if(defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); + else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); + scalar_short_vgroup= (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; dv++; } VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); @@ -466,15 +470,21 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* vertex group support */ if(dvert) { + float scalar; + dv= dvert; if(defgrp_invert) { for(i=0; i<numVerts; i++, dv++) { - vert_angles[i] *= (1.0f - defvert_find_weight(dv, defgrp_index)); + scalar= 1.0f - defvert_find_weight(dv, defgrp_index); + scalar= offset_fac_vg + (scalar * offset_fac_vg_inv); + vert_angles[i] *= scalar; } } else { for(i=0; i<numVerts; i++, dv++) { - vert_angles[i] *= defvert_find_weight(dv, defgrp_index); + scalar= defvert_find_weight(dv, defgrp_index); + scalar= offset_fac_vg + (scalar * offset_fac_vg_inv); + vert_angles[i] *= scalar; } } } @@ -689,5 +699,6 @@ ModifierTypeInfo modifierType_Solidify = { /* dependsOnTime */ NULL, /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, - /* foreachIDLink */ NULL + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index f780721ca07..6c825b213b8 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -152,4 +152,6 @@ ModifierTypeInfo modifierType_Subsurf = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; + diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 382358b179e..e30b7f2392d 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -192,4 +192,5 @@ ModifierTypeInfo modifierType_Surface = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 922ae8c1e92..912c14adfdd 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -434,4 +434,5 @@ ModifierTypeInfo modifierType_UVProject = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 2c77b486263..c1c3604d598 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -140,6 +140,11 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u walk(userData, ob, (ID **)&wmd->map_object); } +static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData) +{ + walk(userData, ob, md, "texture"); +} + static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode) { @@ -364,4 +369,5 @@ ModifierTypeInfo modifierType_Warp = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ foreachTexLink, }; diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index ca8161fe364..4b5769ff603 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -126,6 +126,12 @@ static void foreachIDLink(ModifierData *md, Object *ob, foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } +static void foreachTexLink(ModifierData *md, Object *ob, + TexWalkFunc walk, void *userData) +{ + walk(userData, ob, md, "texture"); +} + static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *UNUSED(scene), Object *UNUSED(ob), @@ -466,4 +472,5 @@ ModifierTypeInfo modifierType_Wave = { /* dependsOnNormals */ NULL, /* foreachObjectLink */ foreachObjectLink, /* foreachIDLink */ foreachIDLink, + /* foreachTexLink */ foreachTexLink, }; diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index 4bed612144c..8d17c6f5e16 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -26,7 +26,7 @@ if env['WITH_BF_PYTHON']: if env['BF_DEBUG']: defs.append('_DEBUG') -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/python/generic/noise_py_api.c b/source/blender/python/generic/noise_py_api.c index f5761f713a6..7be0998c0a1 100644 --- a/source/blender/python/generic/noise_py_api.c +++ b/source/blender/python/generic/noise_py_api.c @@ -210,8 +210,8 @@ static void randuvec(float v[3]) if((r = 1.f - v[2] * v[2]) > 0.f) { float a = (float)(6.283185307f * frand()); r = (float)sqrt(r); - v[0] = (float)(r * cos(a)); - v[1] = (float)(r * sin(a)); + v[0] = (float)(r * cosf(a)); + v[1] = (float)(r * sinf(a)); } else { v[2] = 1.f; @@ -254,7 +254,7 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) if(!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb)) return NULL; - return PyFloat_FromDouble((2.0 * BLI_gNoise(1.0, x, y, z, 0, nb) - 1.0)); + return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, x, y, z, 0, nb) - 1.0f)); } /*-------------------------------------------------------------------------*/ @@ -264,11 +264,11 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) static void noise_vector(float x, float y, float z, int nb, float v[3]) { /* Simply evaluate noise at 3 different positions */ - v[0] = (float)(2.0 * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, - nb) - 1.0); - v[1] = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); - v[2] = (float)(2.0 * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, - nb) - 1.0); + v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, + nb) - 1.0f); + v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); + v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, + nb) - 1.0f); } static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args) @@ -291,7 +291,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, float amp, out, t; int i; amp = 1.f; - out = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); + out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); if(hard) out = (float)fabs(out); for(i = 1; i < oct; i++) { @@ -299,7 +299,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, x *= freqscale; y *= freqscale; z *= freqscale; - t = (float)(amp * (2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0)); + t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f)); if(hard) t = (float)fabs(t); out += t; diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 8bd6e6c611c..e5e90380d61 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -87,6 +87,14 @@ static double bpy_timer_run; /* time for each python script run */ static double bpy_timer_run_tot; /* accumulate python runs */ #endif +/* use for updating while a python script runs - in case of file load */ +void bpy_context_update(bContext *C) +{ + BPy_SetContext(C); + bpy_import_main_set(CTX_data_main(C)); + BPY_modules_update(C); /* can give really bad results if this isnt here */ +} + void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) { py_call_level++; @@ -95,16 +103,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) *gilstate= PyGILState_Ensure(); if(py_call_level==1) { - - if(C) { // XXX - should always be true. - BPy_SetContext(C); - bpy_import_main_set(CTX_data_main(C)); - } - else { - fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n"); - } - - BPY_modules_update(C); /* can give really bad results if this isnt here */ + bpy_context_update(C); #ifdef TIME_PY_RUN if(bpy_timer_count==0) { @@ -570,6 +569,12 @@ void BPY_modules_load_user(bContext *C) if(bmain==NULL) return; + /* update pointers since this can run from a nested script + * on file load */ + if(py_call_level) { + bpy_context_update(C); + } + bpy_context_set(C, &gilstate); for(text=CTX_data_main(C)->text.first; text; text= text->id.next) { diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 4a17c45ae38..7310878f661 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -52,6 +52,9 @@ #include "WM_types.h" #include "MEM_guardedalloc.h" + +#include "BLI_ghash.h" + #include "BKE_report.h" #include "BKE_context.h" @@ -359,15 +362,18 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) static PyObject *pyop_dir(PyObject *UNUSED(self)) { + GHashIterator *iter= WM_operatortype_iter(); PyObject *list= PyList_New(0), *name; - wmOperatorType *ot; - - for(ot= WM_operatortype_first(); ot; ot= ot->next) { + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + wmOperatorType *ot= BLI_ghashIterator_getValue(iter); + name= PyUnicode_FromString(ot->idname); PyList_Append(list, name); Py_DECREF(name); } - + BLI_ghashIterator_free(iter); + return list; } @@ -397,7 +403,9 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); +#ifdef PYRNA_FREE_SUPPORT pyrna->freeptr= TRUE; +#endif return (PyObject *)pyrna; } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 502b25842de..1b8f986e71c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -84,7 +84,9 @@ int pyrna_struct_validity_check(BPy_StructRNA *pysrna) { if(pysrna->ptr.type) return 0; - PyErr_Format(PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name); + PyErr_Format(PyExc_ReferenceError, + "StructRNA of type %.200s has been removed", + Py_TYPE(pysrna)->tp_name); return -1; } @@ -790,18 +792,23 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self) const char *name; if(!PYRNA_STRUCT_IS_VALID(self)) { - return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", Py_TYPE(self)->tp_name); + return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", + Py_TYPE(self)->tp_name); } /* print name if available */ name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE); if(name) { - ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name); + ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>", + RNA_struct_identifier(self->ptr.type), + name); MEM_freeN((void *)name); return ret; } - return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data); + return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>", + RNA_struct_identifier(self->ptr.type), + self->ptr.data); } static PyObject *pyrna_struct_repr(BPy_StructRNA *self) @@ -811,18 +818,26 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) return pyrna_struct_str(self); /* fallback */ if(RNA_struct_is_ID(self->ptr.type)) { - return PyUnicode_FromFormat("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id->name+2); + return PyUnicode_FromFormat("bpy.data.%s[\"%s\"]", + BKE_idcode_to_name_plural(GS(id->name)), + id->name+2); } else { PyObject *ret; const char *path; path= RNA_path_from_ID_to_struct(&self->ptr); if(path) { - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path); + ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", + BKE_idcode_to_name_plural(GS(id->name)), + id->name+2, + path); MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type)); + ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", + BKE_idcode_to_name_plural(GS(id->name)), + id->name+2, + RNA_struct_identifier(self->ptr.type)); } return ret; @@ -856,7 +871,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) if(type==PROP_COLLECTION) { len= pyrna_prop_collection_length(self); } - else if (RNA_property_array_check(&self->ptr, self->prop)) { + else if (RNA_property_array_check(self->prop)) { len= pyrna_prop_array_length((BPy_PropertyArrayRNA *)self); } @@ -870,7 +885,11 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE); if(name) { - ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); + ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", + type_fmt, + RNA_struct_identifier(self->ptr.type), + RNA_property_identifier(self->prop), + name); MEM_freeN((void *)name); return ret; } @@ -878,11 +897,16 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) if(RNA_property_type(self->prop) == PROP_COLLECTION) { PointerRNA r_ptr; if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { - return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type)); + return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", + type_fmt, + RNA_struct_identifier(r_ptr.type)); } } - return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop)); + return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", + type_fmt, + RNA_struct_identifier(self->ptr.type), + RNA_property_identifier(self->prop)); } static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) @@ -902,12 +926,25 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop)); + ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", + BKE_idcode_to_name_plural(GS(id->name)), + id->name+2, + RNA_property_identifier(self->prop)); } return ret; } + +static PyObject *pyrna_func_repr(BPy_FunctionRNA *self) +{ + return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", + Py_TYPE(self)->tp_name, + RNA_struct_identifier(self->ptr.type), + RNA_function_identifier(self->func)); +} + + static long pyrna_struct_hash(BPy_StructRNA *self) { return _Py_HashPointer(self->ptr.data); @@ -950,11 +987,13 @@ static int pyrna_struct_clear(BPy_StructRNA *self) /* use our own dealloc so we can free a property if we use one */ static void pyrna_struct_dealloc(BPy_StructRNA *self) { +#ifdef PYRNA_FREE_SUPPORT if (self->freeptr && self->ptr.data) { IDP_FreeProperty(self->ptr.data); MEM_freeN(self->ptr.data); self->ptr.data= NULL; } +#endif /* PYRNA_FREE_SUPPORT */ #ifdef USE_WEAKREFS if (self->in_weakreflist != NULL) { @@ -1215,7 +1254,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) PyObject *ret; int type= RNA_property_type(prop); - if (RNA_property_array_check(ptr, prop)) { + if (RNA_property_array_check(prop)) { return pyrna_py_from_array(ptr, prop); } @@ -1344,43 +1383,23 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha return error_val; } -static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw); -static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func) +static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) { - static PyMethodDef func_meth= {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"}; - PyObject *self; - PyObject *ret; - - if(func==NULL) { - PyErr_Format(PyExc_RuntimeError, - "%.200s: type attempted to get NULL function", - RNA_struct_identifier(pyrna->ptr.type)); - return NULL; - } - - self= PyTuple_New(2); - - PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna); - Py_INCREF(pyrna); - - PyTuple_SET_ITEM(self, 1, PyCapsule_New((void *)func, NULL, NULL)); - - ret= PyCFunction_New(&func_meth, self); - Py_DECREF(self); - - return ret; + BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); + pyfunc->ptr= *ptr; + pyfunc->func= func; + return (PyObject *)pyfunc; } - static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { /* XXX hard limits should be checked here */ int type= RNA_property_type(prop); - if (RNA_property_array_check(ptr, prop)) { + if (RNA_property_array_check(prop)) { /* done getting the length */ if(pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) { return -1; @@ -3001,12 +3020,14 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) } /* RNA function only if callback is declared (no optional functions) */ else if ((func= RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) { - ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self, func); + ret= pyrna_func_to_py(&self->ptr, func); } else if (self->ptr.type == &RNA_Context) { bContext *C= self->ptr.data; if(C==NULL) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", + name); ret= NULL; } else { @@ -3065,7 +3086,9 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) } else { #if 0 - PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: attribute \"%.200s\" not found", + name); ret= NULL; #endif /* Include this incase this instance is a subtype of a python class @@ -3181,7 +3204,9 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb const char *attr_str= _PyUnicode_AsString(attr); int ret= RNA_def_property_free_identifier(srna, attr_str); if (ret == -1) { - PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str); + PyErr_Format(PyExc_TypeError, + "struct_meta_idprop.detattr(): '%s' not a dynamic property", + attr_str); return -1; } } @@ -3219,7 +3244,9 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject /* code just raises correct error, context prop's cant be set, unless its apart of the py class */ bContext *C= self->ptr.data; if(C==NULL) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", + name); return -1; } else { @@ -3230,7 +3257,9 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject int done= CTX_data_get(C, name, &newptr, &newlb, &newtype); if(done==1) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context property \"%.200s\" is read-only", + name); BLI_freelistN(&newlb); return -1; } @@ -3303,7 +3332,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject } else if ((func= RNA_struct_find_function(&r_ptr, name))) { PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr); - ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func); + ret= pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func); Py_DECREF(self_collection); return ret; @@ -3374,7 +3403,9 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam } } - PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name); + PyErr_Format(PyExc_AttributeError, + "bpy_prop_collection: attribute \"%.200s\" not found", + name); return -1; } @@ -4059,11 +4090,14 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * } /* error, invalid type given */ - PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", type->tp_name); + PyErr_Format(PyExc_TypeError, + "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", + type->tp_name); return NULL; } else { - PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); + PyErr_Format(PyExc_TypeError, + "bpy_struct.__new__(type): expected a single argument"); return NULL; } } @@ -4088,7 +4122,9 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN return (PyObject *)ret; } else { - PyErr_Format(PyExc_TypeError, "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", type->tp_name); + PyErr_Format(PyExc_TypeError, + "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", + type->tp_name); return NULL; } } @@ -4099,7 +4135,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat int type= RNA_property_type(prop); int flag= RNA_property_flag(prop); - if(RNA_property_array_check(ptr, prop)) { + if(RNA_property_array_check(prop)) { int a, len; if (flag & PROP_DYNAMIC) { @@ -4150,7 +4186,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat } break; default: - PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type); + PyErr_Format(PyExc_TypeError, + "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", + type); ret= NULL; break; } @@ -4248,7 +4286,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat break; } default: - PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); + PyErr_Format(PyExc_TypeError, + "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", + type); ret= NULL; break; } @@ -4257,11 +4297,32 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat return ret; } -static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) +/* Use to replace PyDict_GetItemString() when the overhead of converting a + * string into a python unicode is higher than a non hash lookup. + * works on small dict's such as keyword args. */ +static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) +{ + PyObject *key= NULL; + Py_ssize_t pos = 0; + PyObject *value = NULL; + + /* case not, search for it in the script's global dictionary */ + while (PyDict_Next(dict, &pos, &key, &value)) { + if(PyUnicode_Check(key)) { + if(strcmp(key_lookup, _PyUnicode_AsString(key))==0) { + return value; + } + } + } + + return NULL; +} + +static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ - PointerRNA *self_ptr= &(((BPy_DummyPointerRNA *)PyTuple_GET_ITEM(self, 0))->ptr); - FunctionRNA *self_func= PyCapsule_GetPointer(PyTuple_GET_ITEM(self, 1), NULL); + PointerRNA *self_ptr= &self->ptr; + FunctionRNA *self_func= self->func; PointerRNA funcptr; ParameterList parms; @@ -4269,7 +4330,6 @@ static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) PropertyRNA *parm; PyObject *ret, *item; int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg; - const char *parm_id; PropertyRNA *pret_single= NULL; void *retdata_single= NULL; @@ -4345,28 +4405,33 @@ static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) continue; } - parm_id= RNA_property_identifier(parm); item= NULL; if (i < pyargs_len) { item= PyTuple_GET_ITEM(args, i); - i++; - kw_arg= FALSE; } else if (kw != NULL) { - item= PyDict_GetItemString(kw, parm_id); /* borrow ref */ +#if 0 + item= PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ +#else + item= small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ +#endif if(item) kw_tot++; /* make sure invalid keywords are not given */ kw_arg= TRUE; } + i++; /* current argument */ + if (item==NULL) { if(flag & PROP_REQUIRED) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", - RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id); + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + RNA_property_identifier(parm)); err= -1; break; } @@ -4393,9 +4458,18 @@ static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) PyErr_Clear(); /* re-raise */ if(kw_arg==TRUE) - snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with keyword argument \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id); + BLI_snprintf(error_prefix, sizeof(error_prefix), + "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + RNA_property_identifier(parm)); else - snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with argument %d, \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), i, parm_id); + BLI_snprintf(error_prefix, sizeof(error_prefix), + "%.200s.%.200s(): error with argument %d, \"%.200s\" - ", + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + i, + RNA_property_identifier(parm)); pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix); @@ -5045,6 +5119,91 @@ static PyTypeObject pyrna_prop_collection_idprop_Type= { NULL }; +/*-----------------------BPy_PropertyRNA method def------------------------------*/ +PyTypeObject pyrna_func_Type= { + PyVarObject_HEAD_INIT(NULL, 0) + "bpy_func", /* tp_name */ + sizeof(BPy_FunctionRNA), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + NULL, /* tp_dealloc */ + NULL, /* printfunc tp_print; */ + NULL, /* getattrfunc tp_getattr; */ + NULL, /* setattrfunc tp_setattr; */ + NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */ + (reprfunc) pyrna_func_repr, /* tp_repr */ + + /* Method suites for standard classes */ + + NULL, /* PyNumberMethods *tp_as_number; */ + NULL, /* PySequenceMethods *tp_as_sequence; */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + + /* will only use these if this is a subtype of a py class */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ +#ifdef USE_WEAKREFS + offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */ +#else + 0, +#endif + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + NULL, /* struct PyGetSetDef *tp_getset; */ + NULL, /* struct _typeobject *tp_base; */ + NULL, /* PyObject *tp_dict; */ + NULL, /* descrgetfunc tp_descr_get; */ + NULL, /* descrsetfunc tp_descr_set; */ + 0, /* long tp_dictoffset; */ + NULL, /* initproc tp_init; */ + NULL, /* allocfunc tp_alloc; */ + NULL, /* newfunc tp_new; */ + /* Low-level free-memory routine */ + NULL, /* freefunc tp_free; */ + /* For PyObject_IS_GC */ + NULL, /* inquiry tp_is_gc; */ + NULL, /* PyObject *tp_bases; */ + /* method resolution order */ + NULL, /* PyObject *tp_mro; */ + NULL, /* PyObject *tp_cache; */ + NULL, /* PyObject *tp_subclasses; */ + NULL, /* PyObject *tp_weaklist; */ + NULL +}; + #ifdef USE_PYRNA_ITER /* --- collection iterator: start --- */ /* wrap rna collection iterator functions */ @@ -5423,7 +5582,9 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) } pyrna->ptr= *ptr; +#ifdef PYRNA_FREE_SUPPORT pyrna->freeptr= FALSE; +#endif #ifdef USE_PYRNA_STRUCT_REFERENCE pyrna->reference= NULL; @@ -5443,7 +5604,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) { BPy_PropertyRNA *pyrna; - if (RNA_property_array_check(ptr, prop) == 0) { + if (RNA_property_array_check(prop) == 0) { PyTypeObject *type; if (RNA_property_type(prop) != PROP_COLLECTION) { @@ -5516,6 +5677,9 @@ void BPY_rna_init(void) if(PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0) return; + if(PyType_Ready(&pyrna_func_Type) < 0) + return; + #ifdef USE_PYRNA_ITER if(PyType_Ready(&pyrna_prop_collection_iter_Type) < 0) return; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 5db352af53d..30f6c02115a 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -62,6 +62,11 @@ #if defined(USE_PYRNA_INVALIDATE_GC) && defined(USE_PYRNA_INVALIDATE_WEAKREF) #error "Only 1 reference check method at a time!" #endif + +/* only used by operator introspection get_rna(), this is only used for doc gen + * so prefer the leak to the memory bloat for now. */ +// #define PYRNA_FREE_SUPPORT + /* --- end bpy build options --- */ struct ID; @@ -71,6 +76,7 @@ extern PyTypeObject pyrna_struct_Type; extern PyTypeObject pyrna_prop_Type; extern PyTypeObject pyrna_prop_array_Type; extern PyTypeObject pyrna_prop_collection_Type; +extern PyTypeObject pyrna_func_Type; #define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type)) #define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type) @@ -107,7 +113,10 @@ typedef struct { * hold onto the collection iterator to prevent it from freeing allocated data we may use */ PyObject *reference; #endif /* !USE_PYRNA_STRUCT_REFERENCE */ + +#ifdef PYRNA_FREE_SUPPORT int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ +#endif /* PYRNA_FREE_SUPPORT */ } BPy_StructRNA; typedef struct { @@ -142,6 +151,15 @@ typedef struct { CollectionPropertyIterator iter; } BPy_PropertyCollectionIterRNA; +typedef struct { + PyObject_HEAD /* required python macro */ +#ifdef USE_WEAKREFS + PyObject *in_weakreflist; +#endif + PointerRNA ptr; + FunctionRNA *func; +} BPy_FunctionRNA; + /* cheap trick */ #define BPy_BaseTypeRNA BPy_PropertyRNA diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 30d83e196ba..8bde1db96ca 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -107,7 +107,7 @@ static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefi return -1; } - if(RNA_property_array_check(&r_ptr, prop) == 0) { + if(RNA_property_array_check(prop) == 0) { if((*index) == -1) { *index= 0; } diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index 9843a57e0f2..e50ce233671 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -285,17 +285,20 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int int totdim= RNA_property_array_dimension(ptr, prop, NULL); const int seq_size= PySequence_Size(seq); - /* General note for 'data' being NULL or PySequence_GetItem() failing. + /* Regarding PySequence_GetItem() failing. * * This should never be NULL since we validated it, _but_ some triky python * developer could write their own sequence type which succeeds on - * validating but fails later somehow, so include checks for safety. */ + * validating but fails later somehow, so include checks for safety. + */ + + /* Note that 'data can be NULL' */ if(seq_size == -1) { return NULL; } - for (i= 0; (i < seq_size) && data; i++) { + for (i= 0; i < seq_size; i++) { PyObject *item= PySequence_GetItem(seq, i); if(item) { if (dim + 1 < totdim) { diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index b16c8fe2e8c..09fbdf96ed2 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -51,6 +51,7 @@ short BPy_errors_to_report(struct ReportList *reports); struct bContext *BPy_GetContext(void); void BPy_SetContext(struct bContext *C); +extern void bpy_context_update(struct bContext *C); extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate); extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate); #endif diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index a954c07c98d..56c1334ecac 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -37,8 +37,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -extern void PyC_LineSpit(void); - #define MAX_DIMENSIONS 4 /* Swizzle axes get packed into a single value that is used as a closure. Each @@ -1161,28 +1159,18 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) } else if (vec1) { if (MatrixObject_Check(v2)) { - extern void PyC_LineSpit(void); - - /* VEC * MATRIX */ - /* this is deprecated!, use the reverse instead */ - float tvec[MAX_DIMENSIONS]; - /* ------ to be removed ------*/ -#ifndef MATH_STANDALONE -#ifdef WITH_ASSERT_ABORT +#if 1 PyErr_SetString(PyExc_ValueError, "(Vector * Matrix) is now removed, reverse the " "order (promoted to an Error for Debug builds)"); return NULL; #else - printf("Warning: (Vector * Matrix) is now deprecated, " - "reverse the multiplication order in the script.\n"); - PyC_LineSpit(); -#endif -#endif /* ifndef MATH_STANDALONE */ -/* ------ to be removed ------*/ + /* VEC * MATRIX */ + /* this is deprecated!, use the reverse instead */ + float tvec[MAX_DIMENSIONS]; if(BaseMath_ReadCallback((MatrixObject *)v2) == -1) return NULL; @@ -1191,9 +1179,18 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) } return newVectorObject(tvec, vec1->size, Py_NEW, Py_TYPE(vec1)); +#endif +/* ------ to be removed ------*/ } else if (QuaternionObject_Check(v2)) { /* VEC * QUAT */ +/* ------ to be removed ------*/ +#if 1 + PyErr_SetString(PyExc_ValueError, + "(Vector * Quat) is now removed, reverse the " + "order (promoted to an Error for Debug builds)"); + return NULL; +#else QuaternionObject *quat2 = (QuaternionObject*)v2; float tvec[3]; @@ -1207,26 +1204,11 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) return NULL; } - -/* ------ to be removed ------*/ -#ifndef MATH_STANDALONE -#ifdef WITH_ASSERT_ABORT - PyErr_SetString(PyExc_ValueError, - "(Vector * Quat) is now removed, reverse the " - "order (promoted to an Error for Debug builds)"); - return NULL; -#else - printf("Warning: (Vector * Quat) is now deprecated, " - "reverse the multiplication order in the script.\n"); - PyC_LineSpit(); -#endif -#endif /* ifndef MATH_STANDALONE */ -/* ------ to be removed ------*/ - - copy_v3_v3(tvec, vec1->vec); mul_qt_v3(quat2->quat, tvec); return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1)); +#endif +/* ------ to be removed ------*/ } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC * FLOAT */ return vector_mul_float(vec1, scalar); @@ -1260,6 +1242,14 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) /* only support vec*=float and vec*=mat vec*=vec result is a float so that wont work */ if (MatrixObject_Check(v2)) { +/* ------ to be removed ------*/ +#if 1 + PyErr_SetString(PyExc_ValueError, + "(Vector *= Matrix) is now removed, reverse the " + "order (promoted to an Error for Debug builds) " + "and uses the non in-place multiplication."); + return NULL; +#else float rvec[MAX_DIMENSIONS]; if(BaseMath_ReadCallback((MatrixObject *)v2) == -1) return NULL; @@ -1267,28 +1257,21 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) if(column_vector_multiplication(rvec, vec, (MatrixObject*)v2) == -1) return NULL; - -/* ------ to be removed ------*/ -#ifndef MATH_STANDALONE -#ifdef WITH_ASSERT_ABORT - PyErr_SetString(PyExc_ValueError, - "(Vector *= Matrix) is now removed, reverse the " - "order (promoted to an Error for Debug builds) " - "and uses the non in-place multiplication."); - return NULL; -#else - printf("Warning: (Vector *= Matrix) is now deprecated, " - "reverse the (non in-place) multiplication order in the script.\n"); - PyC_LineSpit(); + memcpy(vec->vec, rvec, sizeof(float) * vec->size); #endif -#endif /* ifndef MATH_STANDALONE */ /* ------ to be removed ------*/ - - - memcpy(vec->vec, rvec, sizeof(float) * vec->size); } else if (QuaternionObject_Check(v2)) { /* VEC *= QUAT */ + +/* ------ to be removed ------*/ +#if 1 + PyErr_SetString(PyExc_ValueError, + "(Vector *= Quat) is now removed, reverse the " + "order (promoted to an Error for Debug builds) " + "and uses the non in-place multiplication."); + return NULL; +#else QuaternionObject *quat2 = (QuaternionObject*)v2; if(vec->size != 3) { @@ -1302,25 +1285,9 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) return NULL; } - -/* ------ to be removed ------*/ -#ifndef MATH_STANDALONE -#ifdef WITH_ASSERT_ABORT - PyErr_SetString(PyExc_ValueError, - "(Vector *= Quat) is now removed, reverse the " - "order (promoted to an Error for Debug builds) " - "and uses the non in-place multiplication."); - return NULL; -#else - printf("Warning: (Vector *= Quat) is now deprecated, " - "reverse the (non in-place) multiplication order in the script.\n"); - PyC_LineSpit(); + mul_qt_v3(quat2->quat, vec->vec); #endif -#endif /* ifndef MATH_STANDALONE */ /* ------ to be removed ------*/ - - - mul_qt_v3(quat2->quat, vec->vec); } else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC *= FLOAT */ mul_vn_fl(vec->vec, vec->size, scalar); @@ -1728,6 +1695,21 @@ static int Vector_setLength(VectorObject *self, PyObject *value) return 0; } +/* vector.length_squared */ +static PyObject *Vector_getLengthSquared(VectorObject *self, void *UNUSED(closure)) +{ + double dot = 0.0f; + int i; + + if(BaseMath_ReadCallback(self) == -1) + return NULL; + + for(i = 0; i < self->size; i++){ + dot += (double)(self->vec[i] * self->vec[i]); + } + return PyFloat_FromDouble(dot); +} + /* Get a new Vector according to the provided swizzle. This function has little error checking, as we are in control of the inputs: the closure is set by us in Vector_createSwizzleGetSeter. */ @@ -1851,6 +1833,7 @@ static PyGetSetDef Vector_getseters[] = { {(char *)"z", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector Z axis (3D Vectors only).\n\n:type: float", (void *)2}, {(char *)"w", (getter)Vector_getAxis, (setter)Vector_setAxis, (char *)"Vector W axis (4D Vectors only).\n\n:type: float", (void *)3}, {(char *)"length", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, + {(char *)"length_squared", (getter)Vector_getLengthSquared, (setter)NULL, (char *)"Vector length squared (v.dot(v)).\n\n:type: float", NULL}, {(char *)"magnitude", (getter)Vector_getLength, (setter)Vector_setLength, (char *)"Vector Length.\n\n:type: float", NULL}, {(char *)"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, (char *)BaseMathObject_Wrapped_doc, NULL}, {(char *)"owner", (getter)BaseMathObject_getOwner, (setter)NULL, (char *)BaseMathObject_Owner_doc, NULL}, diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index bff7797e0c7..4ec1ce3de6b 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -31,7 +31,7 @@ if env['OURPLATFORM'] == 'darwin': cflags_raytrace = env['CFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS'] cxxflags_raytrace = env['CXXFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS'] -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': if env['WITH_BF_RAYOPTIMIZATION']: cflags_raytrace = env['CCFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS'] cxxflags_raytrace = env['CXXFLAGS'] + env['BF_RAYOPTIMIZATION_SSE_FLAGS'] diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index b385b507707..7033ec27fc0 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -192,10 +192,10 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), /* minimal free space (starting at camera) */ starmindist= wrld->starmindist; - if (stargrid <= 0.10) return; + if (stargrid <= 0.10f) return; if (re) re->flag |= R_HALO; - else stargrid *= 1.0; /* then it draws fewer */ + else stargrid *= 1.0f; /* then it draws fewer */ if(re) invert_m4_m4(mat, re->viewmat); else unit_m4(mat); @@ -267,17 +267,17 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), if (alpha >= clipend) alpha = 0.0; else if (alpha <= starmindist) alpha = 0.0; - else if (alpha <= 2.0 * starmindist) { + else if (alpha <= 2.0f * starmindist) { alpha = (alpha - starmindist) / starmindist; } else { - alpha -= 2.0 * starmindist; - alpha /= (clipend - 2.0 * starmindist); - alpha = 1.0 - alpha; + alpha -= 2.0f * starmindist; + alpha /= (clipend - 2.0f * starmindist); + alpha = 1.0f - alpha; } } - if (alpha != 0.0) { + if (alpha != 0.0f) { fac = force * BLI_drand(); har = initstar(re, obr, vec, fac); @@ -822,7 +822,7 @@ static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int d if(obr->totvert==0) return; asverts= MEM_callocN(sizeof(ASvert)*obr->totvert, "all smooth verts"); - thresh= cos( M_PI*(0.5f+(float)degr)/180.0 ); + thresh= cosf((float)M_PI*(0.5f+(float)degr)/180.0f ); /* step zero: give faces normals of original mesh, if this is provided */ @@ -1046,9 +1046,9 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par float fac; if(ma->strand_ease!=0.0f) { if(ma->strand_ease<0.0f) - fac= pow(sd->time, 1.0+ma->strand_ease); + fac= pow(sd->time, 1.0f+ma->strand_ease); else - fac= pow(sd->time, 1.0/(1.0f-ma->strand_ease)); + fac= pow(sd->time, 1.0f/(1.0f-ma->strand_ease)); } else fac= sd->time; @@ -1063,7 +1063,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par width= w; /*cross is the radius of the strand so we want it to be half of full width */ - mul_v3_fl(cross,0.5/crosslen); + mul_v3_fl(cross,0.5f/crosslen); } else width/=w; @@ -1984,8 +1984,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem else { /* render normal particles */ if(part->trail_count > 1) { - float length = part->path_end * (1.0 - part->randlength * r_length); - int trail_count = part->trail_count * (1.0 - part->randlength * r_length); + float length = part->path_end * (1.0f - part->randlength * r_length); + int trail_count = part->trail_count * (1.0f - part->randlength * r_length); float ct = (part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time; float dt = length / (trail_count ? (float)trail_count : 1.0f); @@ -2159,7 +2159,7 @@ static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int normalize_v3(view); zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; - if(zn>=0.0) hasize= 0.0; + if(zn>=0.0f) hasize= 0.0f; else hasize*= zn*zn*zn*zn; } @@ -3599,7 +3599,7 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) /* bias is percentage, made 2x larger because of correction for angle of incidence */ /* when a ray is closer to parallel of a face, bias value is increased during render */ - shb->bias= (0.02*lar->bias)*0x7FFFFFFF; + shb->bias= (0.02f*lar->bias)*0x7FFFFFFF; /* halfway method (average of first and 2nd z) reduces bias issues */ if(ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) @@ -3610,7 +3610,7 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) static void area_lamp_vectors(LampRen *lar) { - float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac; + float xsize= 0.5f*lar->area_size, ysize= 0.5f*lar->area_sizey, multifac; /* make it smaller, so area light can be multisampled */ multifac= 1.0f/sqrt((float)lar->ray_totsamp); @@ -3637,7 +3637,7 @@ static void area_lamp_vectors(LampRen *lar) lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; /* only for correction button size, matrix size works on energy */ - lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize); + lar->areasize= lar->dist*lar->dist/(4.0f*xsize*ysize); } /* If lar takes more lamp data, the decoupling will be better. */ @@ -3791,10 +3791,10 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) lar->spotsi= la->spotsize; if(lar->mode & LA_HALO) { - if(lar->spotsi>170.0) lar->spotsi= 170.0; + if(lar->spotsi>170.0f) lar->spotsi= 170.0f; } - lar->spotsi= cos( M_PI*lar->spotsi/360.0 ); - lar->spotbl= (1.0-lar->spotsi)*la->spotblend; + lar->spotsi= cos( M_PI*lar->spotsi/360.0f ); + lar->spotbl= (1.0f-lar->spotsi)*la->spotblend; memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *)); @@ -3813,7 +3813,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) xn= saacos(lar->spotsi); xn= sin(xn)/cos(xn); - lar->spottexfac= 1.0/(xn); + lar->spottexfac= 1.0f/(xn); if(lar->mode & LA_ONLYSHADOW) { if((lar->mode & (LA_SHAD_BUF|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW; @@ -3823,7 +3823,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob) /* set flag for spothalo en initvars */ if(la->type==LA_SPOT && (la->mode & LA_HALO) && (la->buftype != LA_SHADBUF_DEEP)) { - if(la->haint>0.0) { + if(la->haint>0.0f) { re->flag |= R_LAMPHALO; /* camera position (0,0,0) rotate around lamp */ @@ -3990,9 +3990,9 @@ void init_render_world(Render *re) cp= (char *)&re->wrld.fastcol; - cp[0]= 255.0*re->wrld.horr; - cp[1]= 255.0*re->wrld.horg; - cp[2]= 255.0*re->wrld.horb; + cp[0]= 255.0f*re->wrld.horr; + cp[1]= 255.0f*re->wrld.horg; + cp[2]= 255.0f*re->wrld.horb; cp[3]= 1; VECCOPY(re->grvec, re->viewmat[2]); @@ -4047,25 +4047,25 @@ static void set_phong_threshold(ObjectRen *obr) if(vlr->flag & R_SMOOTH) { dot= INPR(vlr->n, vlr->v1->n); dot= ABS(dot); - if(dot>0.9) { + if(dot>0.9f) { thresh+= dot; tot++; } dot= INPR(vlr->n, vlr->v2->n); dot= ABS(dot); - if(dot>0.9) { + if(dot>0.9f) { thresh+= dot; tot++; } dot= INPR(vlr->n, vlr->v3->n); dot= ABS(dot); - if(dot>0.9) { + if(dot>0.9f) { thresh+= dot; tot++; } if(vlr->v4) { dot= INPR(vlr->n, vlr->v4->n); dot= ABS(dot); - if(dot>0.9) { + if(dot>0.9f) { thresh+= dot; tot++; } } @@ -4105,7 +4105,7 @@ static void set_fullsample_trace_flag(Render *re, ObjectRen *obr) else if((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) { /* for blurry reflect/refract, better to take more samples * inside the raytrace than as OSA samples */ - if ((vlr->mat->gloss_mir == 1.0) && (vlr->mat->gloss_tra == 1.0)) + if ((vlr->mat->gloss_mir == 1.0f) && (vlr->mat->gloss_tra == 1.0f)) vlr->flag |= R_FULL_OSA; } } @@ -4221,11 +4221,11 @@ static void check_non_flat_quads(ObjectRen *obr) /* render normals are inverted in render! we calculate normal of single tria here */ flen= normal_tri_v3( nor,vlr->v4->co, vlr->v3->co, vlr->v1->co); - if(flen==0.0) normal_tri_v3( nor,vlr->v4->co, vlr->v2->co, vlr->v1->co); + if(flen==0.0f) normal_tri_v3( nor,vlr->v4->co, vlr->v2->co, vlr->v1->co); xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2]; - if(ABS(xn) < 0.999995 ) { // checked on noisy fractal grid + if(ABS(xn) < 0.999995f ) { // checked on noisy fractal grid float d1, d2; @@ -5461,7 +5461,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float * for(j=0;j<3;j++) fsvec[j] = velarray[a].vel[j]; /* (bad) HACK insert average velocity if none is there (see previous comment) */ - if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0)) + if((fsvec[0] == 0.0f) && (fsvec[1] == 0.0f) && (fsvec[2] == 0.0f)) { fsvec[0] = avgvel[0]; fsvec[1] = avgvel[1]; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index e2ab21ef877..66a73b47790 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -595,7 +595,7 @@ static int envcube_isect(EnvMap *env, float *vec, float *answ) if(env->type==ENV_PLANE) { face= 1; - labda= 1.0/vec[2]; + labda= 1.0f/vec[2]; answ[0]= env->viewscale*labda*vec[0]; answ[1]= -env->viewscale*labda*vec[1]; } @@ -603,44 +603,44 @@ static int envcube_isect(EnvMap *env, float *vec, float *answ) /* which face */ if( vec[2]<=-fabs(vec[0]) && vec[2]<=-fabs(vec[1]) ) { face= 0; - labda= -1.0/vec[2]; + labda= -1.0f/vec[2]; answ[0]= labda*vec[0]; answ[1]= labda*vec[1]; } else if( vec[2]>=fabs(vec[0]) && vec[2]>=fabs(vec[1]) ) { face= 1; - labda= 1.0/vec[2]; + labda= 1.0f/vec[2]; answ[0]= labda*vec[0]; answ[1]= -labda*vec[1]; } else if( vec[1]>=fabs(vec[0]) ) { face= 2; - labda= 1.0/vec[1]; + labda= 1.0f/vec[1]; answ[0]= labda*vec[0]; answ[1]= labda*vec[2]; } else if( vec[0]<=-fabs(vec[1]) ) { face= 3; - labda= -1.0/vec[0]; + labda= -1.0f/vec[0]; answ[0]= labda*vec[1]; answ[1]= labda*vec[2]; } else if( vec[1]<=-fabs(vec[0]) ) { face= 4; - labda= -1.0/vec[1]; + labda= -1.0f/vec[1]; answ[0]= -labda*vec[0]; answ[1]= labda*vec[2]; } else { face= 5; - labda= 1.0/vec[0]; + labda= 1.0f/vec[0]; answ[0]= -labda*vec[1]; answ[1]= labda*vec[2]; } } - answ[0]= 0.5+0.5*answ[0]; - answ[1]= 0.5+0.5*answ[1]; + answ[0]= 0.5f+0.5f*answ[0]; + answ[1]= 0.5f+0.5f*answ[1]; return face; } @@ -725,7 +725,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe /* edges? */ - if(texres->ta<1.0) { + if(texres->ta<1.0f) { TexResult texr1, texr2; texr1.nor= texr2.nor= NULL; @@ -756,8 +756,8 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe else texr2.tr= texr2.tg= texr2.tb= texr2.ta= 0.0; fac= (texres->ta+texr1.ta+texr2.ta); - if(fac!=0.0) { - fac= 1.0/fac; + if(fac!=0.0f) { + fac= 1.0f/fac; texres->tr= fac*(texres->ta*texres->tr + texr1.ta*texr1.tr + texr2.ta*texr2.tr ); texres->tg= fac*(texres->ta*texres->tg + texr1.ta*texr1.tg + texr2.ta*texr2.tg ); diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c index 4a16341093c..f88a5d240c3 100644 --- a/source/blender/render/intern/source/gammaCorrectionTables.c +++ b/source/blender/render/intern/source/gammaCorrectionTables.c @@ -107,7 +107,7 @@ void makeGammaTables(float gamma) int i; valid_gamma = gamma; - valid_inv_gamma = 1.0 / gamma; + valid_inv_gamma = 1.0f / gamma; color_step = 1.0 / RE_GAMMA_TABLE_SIZE; inv_color_step = (float) RE_GAMMA_TABLE_SIZE; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 2f09742f130..bea86264af1 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -126,8 +126,8 @@ static float filt_cubic(float x) if (x < 0.0f) x = -x; - if (x < 1.0f) return 0.5*x*x2 - x2 + 2.0f/3.0f; - if (x < 2.0f) return (2.0-x)*(2.0-x)*(2.0-x)/6.0f; + if (x < 1.0f) return 0.5f*x*x2 - x2 + 2.0f/3.0f; + if (x < 2.0f) return (2.0f-x)*(2.0f-x)*(2.0f-x)/6.0f; return 0.0f; } @@ -138,27 +138,27 @@ static float filt_catrom(float x) if (x < 0.0f) x = -x; if (x < 1.0f) return 1.5f*x2*x - 2.5f*x2 + 1.0f; - if (x < 2.0f) return -0.5f*x2*x + 2.5*x2 - 4.0f*x + 2.0f; + if (x < 2.0f) return -0.5f*x2*x + 2.5f*x2 - 4.0f*x + 2.0f; return 0.0f; } static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */ { float b = 1.0f/3.0f, c = 1.0f/3.0f; - float p0 = ( 6.0 - 2.0*b ) / 6.0; - float p2 = (-18.0 + 12.0*b + 6.0*c) / 6.0; - float p3 = ( 12.0 - 9.0*b - 6.0*c) / 6.0; - float q0 = ( 8.0*b + 24.0*c) / 6.0; - float q1 = ( - 12.0*b - 48.0*c) / 6.0; - float q2 = ( 6.0*b + 30.0*c) / 6.0; - float q3 = ( - b - 6.0*c) / 6.0; - - if (x<-2.0) return 0.0; - if (x<-1.0) return (q0-x*(q1-x*(q2-x*q3))); - if (x< 0.0) return (p0+x*x*(p2-x*p3)); - if (x< 1.0) return (p0+x*x*(p2+x*p3)); - if (x< 2.0) return (q0+x*(q1+x*(q2+x*q3))); - return 0.0; + float p0 = ( 6.0f - 2.0f*b ) / 6.0f; + float p2 = (-18.0f + 12.0f*b + 6.0f*c) / 6.0f; + float p3 = ( 12.0f - 9.0f*b - 6.0f*c) / 6.0f; + float q0 = ( 8.0f*b + 24.0f*c) / 6.0f; + float q1 = ( - 12.0f *b - 48.0f*c) / 6.0f; + float q2 = ( 6.0f *b + 30.0f*c) / 6.0f; + float q3 = ( - b - 6.0f*c) / 6.0f; + + if (x<-2.0f) return 0.0f; + if (x<-1.0f) return (q0-x*(q1-x*(q2-x*q3))); + if (x< 0.0f) return (p0+x*x*(p2-x*p3)); + if (x< 1.0f) return (p0+x*x*(p2+x*p3)); + if (x< 2.0f) return (q0+x*(q1+x*(q2+x*q3))); + return 0.0f; } /* x ranges from -1 to 1 */ @@ -170,16 +170,16 @@ float RE_filter_value(int type, float x) switch(type) { case R_FILTER_BOX: - if(x>1.0) return 0.0f; - return 1.0; + if(x>1.0f) return 0.0f; + return 1.0f; case R_FILTER_TENT: - if(x>1.0) return 0.0f; + if(x>1.0f) return 0.0f; return 1.0f-x; case R_FILTER_GAUSS: x*= gaussfac; - return (1.0/exp(x*x) - 1.0/exp(gaussfac*gaussfac*2.25)); + return (1.0f/expf(x*x) - 1.0f/expf(gaussfac*gaussfac*2.25f)); case R_FILTER_MITCH: return filt_mitchell(x*gaussfac); @@ -221,7 +221,7 @@ static float calc_weight(Render *re, float *weight, int i, int j) case R_FILTER_GAUSS: x = dist*re->r.gauss; - weight[a]= (1.0/exp(x*x) - 1.0/exp(re->r.gauss*re->r.gauss*2.25)); + weight[a]= (1.0f/expf(x*x) - 1.0f/expf(re->r.gauss*re->r.gauss*2.25f)); break; case R_FILTER_MITCH: @@ -309,7 +309,7 @@ void make_sample_tables(Render *re) st->centmask= MEM_mallocN((1<<re->osa), "Initfilt3"); for(a=0; a<16; a++) { - st->centLut[a]= -0.45+((float)a)/16.0; + st->centLut[a]= -0.45f+((float)a)/16.0f; } /* calculate totw */ @@ -327,7 +327,7 @@ void make_sample_tables(Render *re) memset(weight, 0, sizeof(weight)); calc_weight(re, weight, i, j); - for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw); + for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0f/totw); m3= st->fmask1[ 3*(j+1)+i+1 ]; m4= st->fmask2[ 3*(j+1)+i+1 ]; @@ -430,9 +430,9 @@ void make_sample_tables(Render *re) for(a= (1<<re->osa)-1; a>0; a--) { val= st->cmask[a & 255] + st->cmask[a>>8]; - i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val); + i= 8+(15.9f*(fpy1[a & 255]+fpy2[a>>8])/val); CLAMP(i, 0, 15); - j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val); + j= 8+(15.9f*(fpx1[a & 255]+fpx2[a>>8])/val); CLAMP(j, 0, 15); i= j + (i<<4); st->centmask[a]= i; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index 0aa65479a4f..54137c62d22 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1414,7 +1414,7 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f if(env) { /* sky shading using bent normal */ if(ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) { - fac= 0.5*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]); + fac= 0.5f*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]); env[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr; env[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng; env[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb; diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index c2e34e2a70d..d945436be6b 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -68,11 +68,11 @@ extern struct Render R; /* Threshold for a 'full' pixel: pixels with alpha above this level are */ /* considered opaque This is the decimal value for 0xFFF0 / 0xFFFF */ -#define RE_FULL_COLOR_FLOAT 0.9998 +#define RE_FULL_COLOR_FLOAT 0.9998f /* Threshold for an 'empty' pixel: pixels with alpha above this level are */ /* considered completely transparent. This is the decimal value */ /* for 0x000F / 0xFFFF */ -#define RE_EMPTY_COLOR_FLOAT 0.0002 +#define RE_EMPTY_COLOR_FLOAT 0.0002f /* ------------------------------------------------------------------------- */ @@ -82,7 +82,7 @@ void addAlphaOverFloat(float *dest, float *source) /* d = s + (1-alpha_s)d*/ float mul; - mul= 1.0 - source[3]; + mul= 1.0f - source[3]; dest[0]= (mul*dest[0]) + source[0]; dest[1]= (mul*dest[1]) + source[1]; @@ -98,7 +98,7 @@ void addAlphaUnderFloat(float *dest, float *source) { float mul; - mul= 1.0 - dest[3]; + mul= 1.0f - dest[3]; dest[0]+= (mul*source[0]); dest[1]+= (mul*source[1]); @@ -115,7 +115,7 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac) /* Addfac is a number between 0 and 1: rescale */ /* final target is to diminish the influence of dest when addfac rises */ - m = 1.0 - ( source[3] * ((255.0 - addfac) / 255.0)); + m = 1.0f - ( source[3] * ((255 - addfac) / 255.0f)); /* blend colors*/ c= (m * dest[0]) + source[0]; @@ -178,7 +178,7 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w) a= j; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { rb1[0]+= val*r; rb1[1]+= val*g; rb1[2]+= val*b; @@ -187,7 +187,7 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w) a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { rb2[0]+= val*r; rb2[1]+= val*g; rb2[2]+= val*b; @@ -196,7 +196,7 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w) a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { rb3[0]+= val*r; rb3[1]+= val*g; rb3[2]+= val*b; @@ -345,21 +345,21 @@ void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row a= j; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { for(i= 0; i<pixsize; i++) rb1[i]+= val*in[i]; } a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { for(i= 0; i<pixsize; i++) rb2[i]+= val*in[i]; } a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); - if(val!=0.0) { + if(val!=0.0f) { for(i= 0; i<pixsize; i++) rb3[i]+= val*in[i]; } @@ -396,5 +396,3 @@ void addalphaAddFloat(float *dest, float *source) /* eof pixelblending.c */ - - diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index 56a1c870904..febfea89f04 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -86,7 +86,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) ir= ig= ib= 0.0; VECCOPY(rco, har->co); - dco[0]=dco[1]=dco[2]= 1.0/har->rad; + dco[0]=dco[1]=dco[2]= 1.0f/har->rad; vn= har->no; @@ -114,9 +114,9 @@ static void render_lighting_halo(HaloRen *har, float *colf) if(lar->mode & LA_QUAD) { t= 1.0; - if(lar->ld1>0.0) + if(lar->ld1>0.0f) t= lar->dist/(lar->dist+lar->ld1*ld); - if(lar->ld2>0.0) + if(lar->ld2>0.0f) t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld); lampdist= t; @@ -127,7 +127,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) if(lar->mode & LA_SPHERE) { t= lar->dist - ld; - if(t<0.0) continue; + if(t<0.0f) continue; t/= lar->dist; lampdist*= (t); @@ -155,7 +155,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) if(lar->type==LA_SPOT) { if(lar->mode & LA_SQUARE) { - if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) { + if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) { float x, lvrot[3]; /* rotate view to lampspace */ @@ -165,7 +165,7 @@ static void render_lighting_halo(HaloRen *har, float *colf) x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ - inpr= 1.0/(sqrt(1.0+x*x)); + inpr= 1.0/(sqrt(1.0f+x*x)); } else inpr= 0.0; } @@ -179,21 +179,21 @@ static void render_lighting_halo(HaloRen *har, float *colf) t= inpr-t; i= 1.0; soft= 1.0; - if(t<lar->spotbl && lar->spotbl!=0.0) { + if(t<lar->spotbl && lar->spotbl!=0.0f) { /* soft area */ i= t/lar->spotbl; t= i*i; - soft= (3.0*t-2.0*t*i); + soft= (3.0f*t-2.0f*t*i); inpr*= soft; } if(lar->mode & LA_ONLYSHADOW) { /* if(ma->mode & MA_SHADOW) { */ /* dot product positive: front side face! */ inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; - if(inp>0.0) { + if(inp>0.0f) { /* testshadowbuf==0.0 : 100% shadow */ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f); - if( shadfac>0.0 ) { + if( shadfac>0.0f ) { shadfac*= inp*soft*lar->energy; ir -= shadfac; ig -= shadfac; @@ -219,32 +219,32 @@ static void render_lighting_halo(HaloRen *har, float *colf) i= inp; if(lar->type==LA_HEMI) { - i= 0.5*i+0.5; + i= 0.5f*i+0.5f; } - if(i>0.0) { + if(i>0.0f) { i*= lampdist; } /* shadow */ - if(i> -0.41) { /* heuristic valua! */ + if(i> -0.41f) { /* heuristic valua! */ shadfac= 1.0; if(lar->shb) { shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f); - if(shadfac==0.0) continue; + if(shadfac==0.0f) continue; i*= shadfac; } } - if(i>0.0) { + if(i>0.0f) { ir+= i*lacol[0]; ig+= i*lacol[1]; ib+= i*lacol[2]; } } - if(ir<0.0) ir= 0.0; - if(ig<0.0) ig= 0.0; - if(ib<0.0) ib= 0.0; + if(ir<0.0f) ir= 0.0f; + if(ig<0.0f) ig= 0.0f; + if(ib<0.0f) ib= 0.0f; colf[0]*= ir; colf[1]*= ig; @@ -301,7 +301,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, } else alpha= har->alfa; - if(alpha==0.0) + if(alpha==0.0f) return 0; /* soften the halo if it intersects geometry */ @@ -355,15 +355,15 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, fac= fabs( rc[1]*(har->rad*fabs(rc[0]) - radist) ); - if(fac< 1.0) { - ringf+= (1.0-fac); + if(fac< 1.0f) { + ringf+= (1.0f-fac); } } } if(har->type & HA_VECT) { dist= fabs( har->cos*(yn) - har->sin*(xn) )/har->rad; - if(dist>1.0) dist= 1.0; + if(dist>1.0f) dist= 1.0f; if(har->tex) { zn= har->sin*xn - har->cos*yn; yn= har->cos*xn + har->sin*yn; @@ -374,7 +374,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, if(har->type & HA_FLARECIRC) { - dist= 0.5+fabs(dist-0.5); + dist= 0.5+fabs(dist-0.5f); } @@ -418,7 +418,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, float ster, angle; /* rotation */ angle= atan2(yn, xn); - angle*= (1.0+0.25*har->starpoints); + angle*= (1.0f+0.25f*har->starpoints); co= cos(angle); si= sin(angle); @@ -426,15 +426,15 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, angle= (co*xn+si*yn)*(co*yn-si*xn); ster= fabs(angle); - if(ster>1.0) { + if(ster>1.0f) { ster= (har->rad)/(ster); - if(ster<1.0) dist*= sqrt(ster); + if(ster<1.0f) dist*= sqrt(ster); } } /* disputable optimize... (ton) */ - if(dist<=0.00001) + if(dist<=0.00001f) return 0; dist*= alpha; @@ -471,7 +471,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, } /* Next, we do the line and ring factor modifications. */ - if(linef!=0.0) { + if(linef!=0.0f) { Material *ma= har->mat; col[0]+= linef * ma->specr; @@ -481,7 +481,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, if(har->type & HA_XALPHA) col[3]+= linef*linef; else col[3]+= linef; } - if(ringf!=0.0) { + if(ringf!=0.0f) { Material *ma= har->mat; col[0]+= ringf * ma->mirr; @@ -516,16 +516,16 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th blend= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]; - if(blend<0.0) skyflag= 0; + if(blend<0.0f) skyflag= 0; blend= fabs(blend); } else if(R.wrld.skytype & WO_SKYPAPER) { - blend= 0.5+ 0.5*view[1]; + blend= 0.5f + 0.5f * view[1]; } else { /* the fraction of how far we are above the bottom of the screen */ - blend= fabs(0.5+ view[1]); + blend= fabs(0.5f + view[1]); } VECCOPY(hor, &R.wrld.horr); @@ -545,8 +545,8 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th do_sky_tex(rco, lo, dxyview, hor, zen, &blend, skyflag, thread); } - if(blend>1.0) blend= 1.0; - blendm= 1.0-blend; + if(blend>1.0f) blend= 1.0f; + blendm= 1.0f-blend; /* No clipping, no conversion! */ if(R.wrld.skytype & WO_SKYBLEND) { @@ -580,8 +580,8 @@ void shadeSunView(float *colf, float *view) VECCOPY(sview, view); normalize_v3(sview); mul_m3_v3(R.imat, sview); - if (sview[2] < 0.0) - sview[2] = 0.0; + if (sview[2] < 0.0f) + sview[2] = 0.0f; normalize_v3(sview); do_init= 0; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 34d3adcf15b..e82e969d502 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -611,12 +611,12 @@ static int refraction(float *refract, float *n, float *view, float index) index = 1.0f/index; fac= 1.0f - (1.0f - dot*dot)*index*index; if(fac<= 0.0f) return 0; - fac= -dot*index + sqrt(fac); + fac= -dot*index + sqrtf(fac); } else { fac= 1.0f - (1.0f - dot*dot)*index*index; if(fac<= 0.0f) return 0; - fac= -dot*index - sqrt(fac); + fac= -dot*index - sqrtf(fac); } refract[0]= index*view[0] + fac*n[0]; @@ -693,7 +693,7 @@ static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr) if(p < 0.0f) p= 0.0f; else if (p > 10.0f) p= 10.0f; - shr->alpha *= pow(d, p); + shr->alpha *= powf(d, p); if (shr->alpha > 1.0f) shr->alpha= 1.0f; } @@ -720,11 +720,11 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol, /* if fading out, linear blend against fade color */ float blendfac; - blendfac = 1.0 - len_v3v3(shi->co, is->start)/dist_mir; + blendfac = 1.0f - len_v3v3(shi->co, is->start)/dist_mir; - col[0] = col[0]*blendfac + (1.0 - blendfac)*blendcol[0]; - col[1] = col[1]*blendfac + (1.0 - blendfac)*blendcol[1]; - col[2] = col[2]*blendfac + (1.0 - blendfac)*blendcol[2]; + col[0] = col[0]*blendfac + (1.0f - blendfac)*blendcol[0]; + col[1] = col[1]*blendfac + (1.0f - blendfac)*blendcol[1]; + col[2] = col[2]*blendfac + (1.0f - blendfac)*blendcol[2]; } /* the main recursive tracer itself @@ -870,7 +870,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo col[2]= shr.diff[2] + shr.spec[2]; } - if (dist_mir > 0.0) { + if (dist_mir > 0.0f) { float blendcol[3]; /* max ray distance set, but found an intersection, so fade this color @@ -922,11 +922,11 @@ static void DP_energy(float *table, float *vec, int tot, float xsize, float ysiz } } } - vec[0] += 0.1*min*result[0]/(float)tot; - vec[1] += 0.1*min*result[1]/(float)tot; + vec[0] += 0.1f*min*result[0]/(float)tot; + vec[1] += 0.1f*min*result[1]/(float)tot; // cyclic clamping - vec[0]= vec[0] - xsize*floor(vec[0]/xsize + 0.5); - vec[1]= vec[1] - ysize*floor(vec[1]/ysize + 0.5); + vec[0]= vec[0] - xsize*floorf(vec[0]/xsize + 0.5f); + vec[1]= vec[1] - ysize*floorf(vec[1]/ysize + 0.5f); } // random offset of 1 in 2 @@ -934,7 +934,7 @@ static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float s { float dsizex= sizex*ofsx; float dsizey= sizey*ofsy; - float hsizex= 0.5*sizex, hsizey= 0.5*sizey; + float hsizex= 0.5f*sizex, hsizey= 0.5f*sizey; int x; for(x=tot; x>0; x--, jitter1+=2, jitter2+=2) { @@ -968,8 +968,8 @@ void init_jitter_plane(LampRen *lar) /* fill table with random locations, area_size large */ for(x=0; x<tot; x++, fp+=2) { - fp[0]= (BLI_frand()-0.5)*lar->area_size; - fp[1]= (BLI_frand()-0.5)*lar->area_sizey; + fp[0]= (BLI_frand()-0.5f)*lar->area_size; + fp[1]= (BLI_frand()-0.5f)*lar->area_sizey; } while(iter--) { @@ -1081,8 +1081,8 @@ static void QMC_initPixel(QMCSampler *qsa, int thread) { /* hammersley sequence is fixed, already created in QMCSampler init. * per pixel, gets a random offset. We create separate offsets per thread, for write-safety */ - qsa->offs[thread][0] = 0.5 * BLI_thread_frand(thread); - qsa->offs[thread][1] = 0.5 * BLI_thread_frand(thread); + qsa->offs[thread][0] = 0.5f * BLI_thread_frand(thread); + qsa->offs[thread][1] = 0.5f * BLI_thread_frand(thread); } else { /* SAMP_TYPE_HALTON */ @@ -1136,8 +1136,8 @@ static void QMC_samplePhong(float *vec, QMCSampler *qsa, int thread, int num, fl pz = pow(s[1], blur); sqr = sqrt(1.0f-pz*pz); - vec[0] = cos(phi)*sqr; - vec[1] = sin(phi)*sqr; + vec[0] = (float)(cosf(phi)*sqr); + vec[1] = (float)(sinf(phi)*sqr); vec[2] = 0.0f; } @@ -1148,8 +1148,8 @@ static void QMC_sampleRect(float *vec, QMCSampler *qsa, int thread, int num, flo QMC_getSample(s, qsa, thread, num); - vec[0] = (s[0] - 0.5) * sizex; - vec[1] = (s[1] - 0.5) * sizey; + vec[0] = (float)(s[0] - 0.5) * sizex; + vec[1] = (float)(s[1] - 0.5) * sizey; vec[2] = 0.0f; } @@ -1164,8 +1164,8 @@ static void QMC_sampleDisc(float *vec, QMCSampler *qsa, int thread, int num, flo phi = s[0]*2*M_PI; sqr = sqrt(s[1]); - vec[0] = cos(phi)*sqr* radius/2.0; - vec[1] = sin(phi)*sqr* radius/2.0; + vec[0] = cosf(phi)*sqr* radius/2.0f; + vec[1] = sinf(phi)*sqr* radius/2.0f; vec[2] = 0.0f; } @@ -1177,12 +1177,12 @@ static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num) QMC_getSample(s, qsa, thread, num); - phi = s[0]*2.f*M_PI; + phi = s[0]*2.0*M_PI; sqr = sqrt(s[1]); - vec[0] = cos(phi)*sqr; - vec[1] = sin(phi)*sqr; - vec[2] = 1.f - s[1]*s[1]; + vec[0] = cosf(phi)*sqr; + vec[1] = sinf(phi)*sqr; + vec[2] = (float)(1.0 - s[1]*s[1]); } #if 0 /* currently not used */ @@ -1272,7 +1272,7 @@ static int adaptive_sample_variance(int samples, float *col, float *colsq, float var[1] = (colsq[1] / (float)samples) - (mean[1]*mean[1]); var[2] = (colsq[2] / (float)samples) - (mean[2]*mean[2]); - if ((var[0] * 0.4 < thresh) && (var[1] * 0.3 < thresh) && (var[2] * 0.6 < thresh)) + if ((var[0] * 0.4f < thresh) && (var[1] * 0.3f < thresh) && (var[2] * 0.6f < thresh)) return 1; else return 0; @@ -1283,7 +1283,7 @@ static int adaptive_sample_contrast_val(int samples, float prev, float val, floa /* if the last sample's contribution to the total value was below a small threshold * (i.e. the samples taken are very similar), then taking more samples that are probably * going to be the same is wasting effort */ - if (fabs( prev/(float)(samples-1) - val/(float)samples ) < thresh) { + if (fabsf( prev/(float)(samples-1) - val/(float)samples ) < thresh) { return 1; } else return 0; @@ -1293,10 +1293,10 @@ static float get_avg_speed(ShadeInput *shi) { float pre_x, pre_y, post_x, post_y, speedavg; - pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0:shi->winspeed[0]; - pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0:shi->winspeed[1]; - post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0:shi->winspeed[2]; - post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0:shi->winspeed[3]; + pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[0]; + pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[1]; + post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[2]; + post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[3]; speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0; @@ -1316,7 +1316,7 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr) float v_refract[3], v_refract_new[3]; float sampcol[4], colsq[4]; - float blur = pow(1.0 - shi->mat->gloss_tra, 3); + float blur = powf(1.0f - shi->mat->gloss_tra, 3); short max_samples = shi->mat->samp_gloss_tra; float adapt_thresh = shi->mat->adapt_thresh_tra; @@ -1325,9 +1325,9 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr) colsq[0] = colsq[1] = colsq[2] = 0.0; col[0] = col[1] = col[2] = 0.0; col[3]= shr->alpha; - - if (blur > 0.0) { - if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON; + + if (blur > 0.0f) { + if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON; else samp_type = SAMP_TYPE_HAMMERSLEY; /* all samples are generated per pixel */ @@ -1386,13 +1386,13 @@ static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr) samples++; /* adaptive sampling */ - if (adapt_thresh < 1.0 && samples > max_samples/2) + if (adapt_thresh < 1.0f && samples > max_samples/2) { if (adaptive_sample_variance(samples, col, colsq, adapt_thresh)) break; /* if the pixel so far is very dark, we can get away with less samples */ - if ( (col[0] + col[1] + col[2])/3.0/(float)samples < 0.01 ) + if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f ) max_samples--; } } @@ -1415,18 +1415,18 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f float v_nor_new[3], v_reflect[3]; float sampcol[4], colsq[4]; - float blur = pow(1.0 - shi->mat->gloss_mir, 3); + float blur = powf(1.0f - shi->mat->gloss_mir, 3); short max_samples = shi->mat->samp_gloss_mir; float adapt_thresh = shi->mat->adapt_thresh_mir; - float aniso = 1.0 - shi->mat->aniso_gloss_mir; + float aniso = 1.0f - shi->mat->aniso_gloss_mir; int samples=0; col[0] = col[1] = col[2] = 0.0; colsq[0] = colsq[1] = colsq[2] = 0.0; - if (blur > 0.0) { - if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON; + if (blur > 0.0f) { + if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON; else samp_type = SAMP_TYPE_HAMMERSLEY; /* all samples are generated per pixel */ @@ -1485,22 +1485,22 @@ static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float f samples++; /* adaptive sampling */ - if (adapt_thresh > 0.0 && samples > max_samples/3) + if (adapt_thresh > 0.0f && samples > max_samples/3) { if (adaptive_sample_variance(samples, col, colsq, adapt_thresh)) break; /* if the pixel so far is very dark, we can get away with less samples */ - if ( (col[0] + col[1] + col[2])/3.0/(float)samples < 0.01 ) + if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f ) max_samples--; /* reduce samples when reflection is dim due to low ray mirror blend value or fresnel factor * and when reflection is blurry */ - if (fresnelfac < 0.1 * (blur+1)) { + if (fresnelfac < 0.1f * (blur+1)) { max_samples--; /* even more for very dim */ - if (fresnelfac < 0.05 * (blur+1)) + if (fresnelfac < 0.05f * (blur+1)) max_samples--; } } @@ -1659,7 +1659,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int col[1] = a*col[1] + shr.alpha*shr.combined[1]; col[2] = a*col[2] + shr.alpha*shr.combined[2]; - col[3] = (1.0 - shr.alpha)*a; + col[3] = (1.0f - shr.alpha)*a; } if(depth>0 && col[3]>0.0f) { @@ -1679,7 +1679,7 @@ static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int /* not used, test function for ambient occlusion (yaf: pathlight) */ /* main problem; has to be called within shading loop, giving unwanted recursion */ -static int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) +static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult *shr) { static int counter=0, only_one= 0; extern float hashvectf[]; @@ -1758,8 +1758,8 @@ static void RandomSpherical(float *v) if ((r = 1.f - v[2]*v[2])>0.f) { float a = 6.283185307f*BLI_frand(); r = sqrt(r); - v[0] = r * cos(a); - v[1] = r * sin(a); + v[0] = r * cosf(a); + v[1] = r * sinf(a); } else v[2] = 1.f; } @@ -1956,7 +1956,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env) float speedfac; speedfac = get_avg_speed(shi) * adapt_speed_fac; - CLAMP(speedfac, 1.0, 1000.0); + CLAMP(speedfac, 1.0f, 1000.0f); max_samples /= speedfac; if (max_samples < 5) max_samples = 5; @@ -1985,7 +1985,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env) prev = fac; if(RE_rayobject_raycast(R.raytree, &isec)) { - if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.dist*R.wrld.aodistfac); + if (R.wrld.aomode & WO_AODIST) fac+= expf(-isec.dist*R.wrld.aodistfac); else fac+= 1.0f; } else if(envcolor!=WO_AOPLAIN) { @@ -1998,7 +1998,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env) normalize_v3(view); if(envcolor==WO_AOSKYCOL) { - skyfac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); + skyfac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); env[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr; env[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng; env[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb; @@ -2017,7 +2017,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *ao, float *env) if (qsa->type == SAMP_TYPE_HALTON) { /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */ - if (adapt_thresh > 0.0 && (samples > max_samples/2) ) { + if (adapt_thresh > 0.0f && (samples > max_samples/2) ) { if (adaptive_sample_contrast_val(samples, prev, fac, adapt_thresh)) { break; @@ -2123,7 +2123,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env) /* do the trace */ if(RE_rayobject_raycast(R.raytree, &isec)) { - if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.dist*R.wrld.aodistfac); + if (R.wrld.aomode & WO_AODIST) sh+= expf(-isec.dist*R.wrld.aodistfac); else sh+= 1.0f; } else if(envcolor!=WO_AOPLAIN) { @@ -2136,7 +2136,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env) normalize_v3(view); if(envcolor==WO_AOSKYCOL) { - fac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); + fac= 0.5f*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr; env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng; env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb; @@ -2367,14 +2367,14 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float * if (lar->ray_samp_method == LA_SAMP_HALTON) { /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */ - if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) { + if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0f) && (samples > max_samples / 3)) { if (isec->mode==RE_RAY_SHADOW_TRA) { - if ((shadfac[3] / samples > (1.0-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh)) + if ((shadfac[3] / samples > (1.0f-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh)) break; else if (adaptive_sample_variance(samples, shadfac, colsq, adapt_thresh)) break; } else { - if ((fac / samples > (1.0-adapt_thresh)) || (fac / samples < adapt_thresh)) + if ((fac / samples > (1.0f-adapt_thresh)) || (fac / samples < adapt_thresh)) break; } } diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 63cc87915aa..88f1f2f5e71 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -175,9 +175,9 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres) do_colorband(tex->coba, texres->nor[2], col); fac3= (col[0]+col[1]+col[2]); - texres->nor[0]= 0.3333*(fac0 - fac1); - texres->nor[1]= 0.3333*(fac0 - fac2); - texres->nor[2]= 0.3333*(fac0 - fac3); + texres->nor[0]= 0.3333f*(fac0 - fac1); + texres->nor[1]= 0.3333f*(fac0 - fac2); + texres->nor[2]= 0.3333f*(fac0 - fac3); return; } @@ -203,31 +203,31 @@ static int blend(Tex *tex, float *texvec, TexResult *texres) } if(tex->stype==TEX_LIN) { /* lin */ - texres->tin= (1.0+x)/2.0; + texres->tin= (1.0f+x)/2.0f; } else if(tex->stype==TEX_QUAD) { /* quad */ - texres->tin= (1.0+x)/2.0; - if(texres->tin<0.0) texres->tin= 0.0; + texres->tin= (1.0f+x)/2.0f; + if(texres->tin<0.0f) texres->tin= 0.0f; else texres->tin*= texres->tin; } else if(tex->stype==TEX_EASE) { /* ease */ - texres->tin= (1.0+x)/2.0; - if(texres->tin<=.0) texres->tin= 0.0; - else if(texres->tin>=1.0) texres->tin= 1.0; + texres->tin= (1.0f+x)/2.0f; + if(texres->tin<=0.0f) texres->tin= 0.0f; + else if(texres->tin>=1.0f) texres->tin= 1.0f; else { t= texres->tin*texres->tin; - texres->tin= (3.0*t-2.0*t*texres->tin); + texres->tin= (3.0f*t-2.0f*t*texres->tin); } } else if(tex->stype==TEX_DIAG) { /* diag */ - texres->tin= (2.0+x+y)/4.0; + texres->tin= (2.0f+x+y)/4.0f; } else if(tex->stype==TEX_RAD) { /* radial */ texres->tin= (atan2(y,x) / (2*M_PI) + 0.5); } else { /* sphere TEX_SPHERE */ texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]); - if(texres->tin<0.0) texres->tin= 0.0; + if(texres->tin<0.0f) texres->tin= 0.0f; if(tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */ } @@ -299,7 +299,7 @@ static float tex_tri(float a) const float b = 2*M_PI; const float rmax = 1.0; - a = rmax - 2.0*fabs(floor((a*(1.0/b))+0.5) - (a*(1.0/b))); + a = rmax - 2.0f*fabsf(floorf((a*(1.0f/b))+0.5f) - (a*(1.0f/b))); return a; } @@ -319,18 +319,18 @@ static float wood_int(Tex *tex, float x, float y, float z) if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */ if (wt==TEX_BAND) { - wi = waveform[wf]((x + y + z)*10.0); + wi = waveform[wf]((x + y + z)*10.0f); } else if (wt==TEX_RING) { - wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0); + wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0f); } else if (wt==TEX_BANDNOISE) { wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - wi = waveform[wf]((x + y + z)*10.0 + wi); + wi = waveform[wf]((x + y + z)*10.0f + wi); } else if (wt==TEX_RINGNOISE) { wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0 + wi); + wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0f + wi); } return wi; @@ -370,7 +370,7 @@ static float marble_int(Tex *tex, float x, float y, float z) if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */ - n = 5.0 * (x + y + z); + n = 5.0f * (x + y + z); mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); @@ -417,11 +417,11 @@ static int magic(Tex *tex, float *texvec, TexResult *texres) int n; n= tex->noisedepth; - turb= tex->turbul/5.0; + turb= tex->turbul/5.0f; - x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0 ); - y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0 ); - z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0 ); + x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0f ); + y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0f ); + z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0f ); if(n>0) { x*= turb; y*= turb; @@ -466,17 +466,17 @@ static int magic(Tex *tex, float *texvec, TexResult *texres) } } - if(turb!=0.0) { - turb*= 2.0; + if(turb!=0.0f) { + turb*= 2.0f; x/= turb; y/= turb; z/= turb; } - texres->tr= 0.5-x; - texres->tg= 0.5-y; - texres->tb= 0.5-z; + texres->tr= 0.5f-x; + texres->tg= 0.5f-y; + texres->tb= 0.5f-z; - texres->tin= 0.3333*(texres->tr+texres->tg+texres->tb); + texres->tin= 0.3333f*(texres->tr+texres->tg+texres->tb); BRICONTRGB; texres->ta= 1.0; @@ -494,7 +494,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres) b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - ofs= tex->turbul/200.0; + ofs= tex->turbul/200.0f; if(tex->stype) ofs*=(b2*b2); nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); @@ -732,7 +732,7 @@ static int texnoise(Tex *tex, TexResult *texres) while(loop--) { ran= (ran>>2); val*= (ran & 3); - div*= 3.0; + div*= 3.0f; } texres->tin= ((float)val)/div; @@ -829,18 +829,18 @@ static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float z1= fabs(nor[2]); if(z1>=x1 && z1>=y1) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (y + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (y + 1.0f) / 2.0f; ret= 0; } else if(y1>=x1 && y1>=z1) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 1; } else { - *adr1 = (y + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (y + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 2; } return ret; @@ -884,17 +884,17 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z } if(vlr->puno & proj[1]) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (y + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (y + 1.0f) / 2.0f; } else if(vlr->puno & proj[2]) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 1; } else { - *adr1 = (y + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (y + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 2; } } @@ -922,18 +922,18 @@ static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *ad z1= fabs(nor[2]); if(z1>=x1 && z1>=y1) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (y + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (y + 1.0f) / 2.0f; ret= 0; } else if(y1>=x1 && y1>=z1) { - *adr1 = (x + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (x + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 1; } else { - *adr1 = (y + 1.0) / 2.0; - *adr2 = (z + 1.0) / 2.0; + *adr1 = (y + 1.0f) / 2.0f; + *adr2 = (z + 1.0f) / 2.0f; ret= 2; } return ret; @@ -957,8 +957,8 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d if(R.osa==0) { if(wrap==MTEX_FLAT) { - fx = (t[0] + 1.0) / 2.0; - fy = (t[1] + 1.0) / 2.0; + fx = (t[0] + 1.0f) / 2.0f; + fy = (t[1] + 1.0f) / 2.0f; } else if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]); else if(wrap==MTEX_SPHERE) map_to_sphere( &fx, &fy,t[0], t[1], t[2]); @@ -973,34 +973,34 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d if(tex->xrepeat>1) { float origf= fx *= tex->xrepeat; - if(fx>1.0) fx -= (int)(fx); - else if(fx<0.0) fx+= 1-(int)(fx); + if(fx>1.0f) fx -= (int)(fx); + else if(fx<0.0f) fx+= 1-(int)(fx); if(tex->flag & TEX_REPEAT_XMIR) { int orig= (int)floor(origf); if(orig & 1) - fx= 1.0-fx; + fx= 1.0f-fx; } } if(tex->yrepeat>1) { float origf= fy *= tex->yrepeat; - if(fy>1.0) fy -= (int)(fy); - else if(fy<0.0) fy+= 1-(int)(fy); + if(fy>1.0f) fy -= (int)(fy); + else if(fy<0.0f) fy+= 1-(int)(fy); if(tex->flag & TEX_REPEAT_YMIR) { int orig= (int)floor(origf); if(orig & 1) - fy= 1.0-fy; + fy= 1.0f-fy; } } } /* crop */ - if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { + if(tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) { fac1= tex->cropxmax - tex->cropxmin; fx= tex->cropxmin+ fx*fac1; } - if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { + if(tex->cropymin!=0.0f || tex->cropymax!=1.0f) { fac1= tex->cropymax - tex->cropymin; fy= tex->cropymin+ fy*fac1; } @@ -1011,23 +1011,23 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d else { if(wrap==MTEX_FLAT) { - fx= (t[0] + 1.0) / 2.0; - fy= (t[1] + 1.0) / 2.0; - dxt[0]/= 2.0; - dxt[1]/= 2.0; - dxt[2]/= 2.0; - dyt[0]/= 2.0; - dyt[1]/= 2.0; - dyt[2]/= 2.0; + fx= (t[0] + 1.0f) / 2.0f; + fy= (t[1] + 1.0f) / 2.0f; + dxt[0]/= 2.0f; + dxt[1]/= 2.0f; + dxt[2]/= 2.0f; + dyt[0]/= 2.0f; + dyt[1]/= 2.0f; + dyt[2]/= 2.0f; } else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) { /* exception: the seam behind (y<0.0) */ ok= 1; - if(t[1]<=0.0) { + if(t[1]<=0.0f) { fx= t[0]+dxt[0]; fy= t[0]+dyt[0]; - if(fx>=0.0 && fy>=0.0 && t[0]>=0.0); - else if(fx<=0.0 && fy<=0.0 && t[0]<=0.0); + if(fx>=0.0f && fy>=0.0f && t[0]>=0.0f); + else if(fx<=0.0f && fy<=0.0f && t[0]<=0.0f); else ok= 0; } if(ok) { @@ -1046,10 +1046,10 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d else { if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]); else map_to_sphere( &fx, &fy,t[0], t[1], t[2]); - dxt[0]/= 2.0; - dxt[1]/= 2.0; - dyt[0]/= 2.0; - dyt[1]/= 2.0; + dxt[0]/= 2.0f; + dxt[1]/= 2.0f; + dyt[0]/= 2.0f; + dyt[1]/= 2.0f; } } else { @@ -1143,13 +1143,13 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d } /* crop */ - if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { + if(tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) { fac1= tex->cropxmax - tex->cropxmin; fx= tex->cropxmin+ fx*fac1; dxt[0]*= fac1; dyt[0]*= fac1; } - if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { + if(tex->cropymin!=0.0f || tex->cropymax!=1.0f) { fac1= tex->cropymax - tex->cropymin; fy= tex->cropymin+ fy*fac1; dxt[1]*= fac1; @@ -1220,7 +1220,7 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRes * artificer: added the use of tmpvec to avoid scaling texvec */ VECCOPY(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0/tex->noisesize); + mul_v3_fl(tmpvec, 1.0f/tex->noisesize); switch(tex->stype) { case TEX_MFRACTAL: @@ -1242,7 +1242,7 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRes * artificer: added the use of tmpvec to avoid scaling texvec */ VECCOPY(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0/tex->noisesize); + mul_v3_fl(tmpvec, 1.0f/tex->noisesize); retval= voronoiTex(tex, tmpvec, texres); break; @@ -1251,7 +1251,7 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRes * artificer: added the use of tmpvec to avoid scaling texvec */ VECCOPY(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0/tex->noisesize); + mul_v3_fl(tmpvec, 1.0f/tex->noisesize); retval= mg_distNoiseTex(tex, tmpvec, texres); break; @@ -1381,7 +1381,7 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg switch(blendtype) { case MTEX_BLEND: fact*= facg; - facm= 1.0-fact; + facm= 1.0f-fact; in[0]= (fact*tex[0] + facm*out[0]); in[1]= (fact*tex[1] + facm*out[1]); @@ -1390,7 +1390,7 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg case MTEX_MUL: fact*= facg; - facm= 1.0-facg; + facm= 1.0f-facg; in[0]= (facm+fact*tex[0])*out[0]; in[1]= (facm+fact*tex[1])*out[1]; in[2]= (facm+fact*tex[2])*out[2]; @@ -1398,28 +1398,28 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg case MTEX_SCREEN: fact*= facg; - facm= 1.0-facg; - in[0]= 1.0 - (facm+fact*(1.0-tex[0])) * (1.0-out[0]); - in[1]= 1.0 - (facm+fact*(1.0-tex[1])) * (1.0-out[1]); - in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]); + facm= 1.0f-facg; + in[0]= 1.0f - (facm+fact*(1.0f-tex[0])) * (1.0f-out[0]); + in[1]= 1.0f - (facm+fact*(1.0f-tex[1])) * (1.0f-out[1]); + in[2]= 1.0f - (facm+fact*(1.0f-tex[2])) * (1.0f-out[2]); break; case MTEX_OVERLAY: fact*= facg; - facm= 1.0-facg; + facm= 1.0f-facg; if(out[0] < 0.5f) in[0] = out[0] * (facm + 2.0f*fact*tex[0]); else - in[0] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[0])) * (1.0 - out[0]); + in[0] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[0])) * (1.0f - out[0]); if(out[1] < 0.5f) in[1] = out[1] * (facm + 2.0f*fact*tex[1]); else - in[1] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[1])) * (1.0 - out[1]); + in[1] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[1])) * (1.0f - out[1]); if(out[2] < 0.5f) in[2] = out[2] * (facm + 2.0f*fact*tex[2]); else - in[2] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[2])) * (1.0 - out[2]); + in[2] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[2])) * (1.0f - out[2]); break; case MTEX_SUB: @@ -1433,20 +1433,20 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg case MTEX_DIV: fact*= facg; - facm= 1.0-fact; + facm= 1.0f-fact; - if(tex[0]!=0.0) + if(tex[0]!=0.0f) in[0]= facm*out[0] + fact*out[0]/tex[0]; - if(tex[1]!=0.0) + if(tex[1]!=0.0f) in[1]= facm*out[1] + fact*out[1]/tex[1]; - if(tex[2]!=0.0) + if(tex[2]!=0.0f) in[2]= facm*out[2] + fact*out[2]/tex[2]; break; case MTEX_DIFF: fact*= facg; - facm= 1.0-fact; + facm= 1.0f-fact; in[0]= facm*out[0] + fact*fabs(tex[0]-out[0]); in[1]= facm*out[1] + fact*fabs(tex[1]-out[1]); in[2]= facm*out[2] + fact*fabs(tex[2]-out[2]); @@ -1454,7 +1454,7 @@ void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg case MTEX_DARK: fact*= facg; - facm= 1.0-fact; + facm= 1.0f-fact; col= tex[0]+((1-tex[0])*facm); if(col < out[0]) in[0]= col; else in[0]= out[0]; @@ -1516,7 +1516,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen facg= fabsf(facg); fact*= facg; - facm= 1.0-fact; + facm= 1.0f-fact; if(flip) SWAP(float, fact, facm); switch(blendtype) { @@ -1525,21 +1525,21 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen break; case MTEX_MUL: - facm= 1.0-facg; + facm= 1.0f-facg; in= (facm+fact*tex)*out; break; case MTEX_SCREEN: - facm= 1.0-facg; - in= 1.0-(facm+fact*(1.0-tex))*(1.0-out); + facm= 1.0f-facg; + in= 1.0f-(facm+fact*(1.0f-tex))*(1.0f-out); break; case MTEX_OVERLAY: - facm= 1.0-facg; + facm= 1.0f-facg; if(out < 0.5f) in = out * (facm + 2.0f*fact*tex); else - in = 1.0f - (facm + 2.0f*fact*(1.0 - tex)) * (1.0 - out); + in = 1.0f - (facm + 2.0f*fact*(1.0f - tex)) * (1.0f - out); break; case MTEX_SUB: @@ -1549,7 +1549,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen break; case MTEX_DIV: - if(tex!=0.0) + if(tex!=0.0f) in= facm*out + fact*out/tex; break; @@ -1568,15 +1568,15 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen break; case MTEX_SOFT_LIGHT: - scf=1.0 - (1.0 - tex) * (1.0 - out); - in= facm*out + fact * ((1.0 - out) * tex * out) + (out * scf); + scf=1.0f - (1.0f - tex) * (1.0f - out); + in= facm*out + fact * ((1.0f - out) * tex * out) + (out * scf); break; case MTEX_LIN_LIGHT: - if (tex > 0.5) - in = out + fact*(2*(tex - 0.5)); + if (tex > 0.5f) + in = out + fact*(2.0f*(tex - 0.5f)); else - in = out + fact*(2*tex - 1); + in = out + fact*(2.0f*tex - 1.0f); break; } @@ -2099,14 +2099,21 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { if(tex->ima) { - // crazy hack solution that gives results similar to normal mapping - part 2 float vec[2]; + int dimx=512, dimy=512; + ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); + if (ibuf) { + dimx = ibuf->x; + dimy = ibuf->y; + } + + // crazy hack solution that gives results similar to normal mapping - part 2 - vec[0] = tex->ima->gen_x*dxt[0]; - vec[1] = tex->ima->gen_y*dxt[1]; + vec[0] = dimx*dxt[0]; + vec[1] = dimy*dxt[1]; dHdx *= 1.0f/len_v2(vec); - vec[0] = tex->ima->gen_x*dyt[0]; - vec[1] = tex->ima->gen_y*dyt[1]; + vec[0] = dimx*dyt[0]; + vec[1] = dimy*dyt[1]; dHdy *= 1.0f/len_v2(vec); } } @@ -2304,16 +2311,16 @@ void do_material_tex(ShadeInput *shi) /* texture output */ if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); rgbnor-= TEX_RGB; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgbnor & TEX_RGB) { - texres.tr= 1.0-texres.tr; - texres.tg= 1.0-texres.tg; - texres.tb= 1.0-texres.tb; + texres.tr= 1.0f-texres.tr; + texres.tg= 1.0f-texres.tg; + texres.tb= 1.0f-texres.tb; } - texres.tin= 1.0-texres.tin; + texres.tin= 1.0f-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgbnor & TEX_RGB) { @@ -2340,8 +2347,8 @@ void do_material_tex(ShadeInput *shi) texres.nor[2]= texres.tb; } else { - float co_nor= 0.5*cos(texres.tin-0.5); - float si= 0.5*sin(texres.tin-0.5); + float co_nor= 0.5*cos(texres.tin-0.5f); + float si= 0.5*sin(texres.tin-0.5f); float f1, f2; f1= shi->vn[0]; @@ -2427,7 +2434,7 @@ void do_material_tex(ShadeInput *shi) // exception for envmap only if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) { fact= texres.tin*mirrfac; - facm= 1.0- fact; + facm= 1.0f- fact; shi->refcol[0]= fact + facm*shi->refcol[0]; shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1]; shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2]; @@ -2572,65 +2579,65 @@ void do_material_tex(ShadeInput *shi) if(rgbnor & TEX_RGB) { if(texres.talpha) texres.tin= texres.ta; - else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } if(mtex->mapto & MAP_REF) { float difffac= mtex->difffac*stencilTin; shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype); - if(shi->refl<0.0) shi->refl= 0.0; + if(shi->refl<0.0f) shi->refl= 0.0f; } if(mtex->mapto & MAP_SPEC) { float specfac= mtex->specfac*stencilTin; shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype); - if(shi->spec<0.0) shi->spec= 0.0; + if(shi->spec<0.0f) shi->spec= 0.0f; } if(mtex->mapto & MAP_EMIT) { float emitfac= mtex->emitfac*stencilTin; shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype); - if(shi->emit<0.0) shi->emit= 0.0; + if(shi->emit<0.0f) shi->emit= 0.0f; } if(mtex->mapto & MAP_ALPHA) { float alphafac= mtex->alphafac*stencilTin; shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype); - if(shi->alpha<0.0) shi->alpha= 0.0; - else if(shi->alpha>1.0) shi->alpha= 1.0; + if(shi->alpha<0.0f) shi->alpha= 0.0f; + else if(shi->alpha>1.0f) shi->alpha= 1.0f; } if(mtex->mapto & MAP_HAR) { float har; // have to map to 0-1 float hardfac= mtex->hardfac*stencilTin; - har= ((float)shi->har)/128.0; - har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype); + har= ((float)shi->har)/128.0f; + har= 128.0f*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype); - if(har<1.0) shi->har= 1; - else if(har>511.0) shi->har= 511; + if(har<1.0f) shi->har= 1; + else if(har>511) shi->har= 511; else shi->har= (int)har; } if(mtex->mapto & MAP_RAYMIRR) { float raymirrfac= mtex->raymirrfac*stencilTin; shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype); - if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0; - else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0; + if(shi->ray_mirror<0.0f) shi->ray_mirror= 0.0f; + else if(shi->ray_mirror>1.0f) shi->ray_mirror= 1.0f; } if(mtex->mapto & MAP_TRANSLU) { float translfac= mtex->translfac*stencilTin; shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype); - if(shi->translucency<0.0) shi->translucency= 0.0; - else if(shi->translucency>1.0) shi->translucency= 1.0; + if(shi->translucency<0.0f) shi->translucency= 0.0f; + else if(shi->translucency>1.0f) shi->translucency= 1.0f; } if(mtex->mapto & MAP_AMB) { float ambfac= mtex->ambfac*stencilTin; shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype); - if(shi->amb<0.0) shi->amb= 0.0; - else if(shi->amb>1.0) shi->amb= 1.0; + if(shi->amb<0.0f) shi->amb= 0.0f; + else if(shi->amb>1.0f) shi->amb= 1.0f; shi->ambr= shi->amb*R.wrld.ambr; shi->ambg= shi->amb*R.wrld.ambg; @@ -2726,16 +2733,16 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa /* texture output */ if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); rgbnor-= TEX_RGB; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgbnor & TEX_RGB) { - texres.tr= 1.0-texres.tr; - texres.tg= 1.0-texres.tg; - texres.tb= 1.0-texres.tb; + texres.tr= 1.0f-texres.tr; + texres.tg= 1.0f-texres.tg; + texres.tb= 1.0f-texres.tb; } - texres.tin= 1.0-texres.tin; + texres.tin= 1.0f-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgbnor & TEX_RGB) { @@ -2792,7 +2799,7 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa if (!(rgbnor & TEX_INT)) { if (rgbnor & TEX_RGB) { if(texres.talpha) texres.tin= texres.ta; - else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } } @@ -2800,25 +2807,25 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa float emitfac= mtex->emitfac*stencilTin; *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype); - if(*val<0.0) *val= 0.0; + if(*val<0.0f) *val= 0.0f; } if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) { float densfac= mtex->densfac*stencilTin; *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype); - CLAMP(*val, 0.0, 1.0); + CLAMP(*val, 0.0f, 1.0f); } if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) { float scatterfac= mtex->scatterfac*stencilTin; *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype); - CLAMP(*val, 0.0, 1.0); + CLAMP(*val, 0.0f, 1.0f); } if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) { float reflfac= mtex->reflfac*stencilTin; *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype); - CLAMP(*val, 0.0, 1.0); + CLAMP(*val, 0.0f, 1.0f); } } } @@ -2862,7 +2869,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) if(osatex) { - dx= 1.0/har->rad; + dx= 1.0f/har->rad; if(mtex->projx) { dxt[0]= mtex->size[0]*dx; @@ -2890,16 +2897,16 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - texres.tr= 1.0-texres.tr; - texres.tg= 1.0-texres.tg; - texres.tb= 1.0-texres.tb; + texres.tr= 1.0f-texres.tr; + texres.tg= 1.0f-texres.tg; + texres.tb= 1.0f-texres.tb; } - else texres.tin= 1.0-texres.tin; + else texres.tin= 1.0f-texres.tin; } /* mapping */ @@ -2926,10 +2933,10 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) } fact= texres.tin*mtex->colfac; - facm= 1.0-fact; + facm= 1.0f-fact; if(mtex->blendtype==MTEX_MUL) { - facm= 1.0-mtex->colfac; + facm= 1.0f-mtex->colfac; } if(mtex->blendtype==MTEX_SUB) fact= -fact; @@ -2949,15 +2956,15 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) colf[1]= (fact*texres.tg + har->g); colf[2]= (fact*texres.tb + har->b); - CLAMP(colf[0], 0.0, 1.0); - CLAMP(colf[1], 0.0, 1.0); - CLAMP(colf[2], 0.0, 1.0); + CLAMP(colf[0], 0.0f, 1.0f); + CLAMP(colf[1], 0.0f, 1.0f); + CLAMP(colf[2], 0.0f, 1.0f); } } if(mtex->mapto & MAP_ALPHA) { if(rgb) { if(texres.talpha) texres.tin= texres.ta; - else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); } colf[3]*= texres.tin; @@ -3007,7 +3014,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f /* only works with texture being "real" */ /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less then -1.0 */ if(lo[0] || lo[1]) { /* check for zero case [#24807] */ - fact= (1.0/M_PI)*saacos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); + fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); tempvec[0]= lo[0]*fact; tempvec[1]= lo[1]*fact; tempvec[2]= 0.0; @@ -3028,13 +3035,13 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f if(mtex->texco==TEXCO_H_TUBEMAP) map_to_tube( tempvec, tempvec+1,lo[0], lo[2], lo[1]); else map_to_sphere( tempvec, tempvec+1,lo[0], lo[2], lo[1]); /* tube/spheremap maps for outside view, not inside */ - tempvec[0]= 1.0-tempvec[0]; + tempvec[0]= 1.0f-tempvec[0]; /* only top half */ - tempvec[1]= 2.0*tempvec[1]-1.0; + tempvec[1]= 2.0f*tempvec[1]-1.0f; tempvec[2]= 0.0; /* and correction for do_2d_mapping */ - tempvec[0]= 2.0*tempvec[0]-1.0; - tempvec[1]= 2.0*tempvec[1]-1.0; + tempvec[0]= 2.0f*tempvec[0]-1.0f; + tempvec[1]= 2.0f*tempvec[1]-1.0f; co= tempvec; } else { @@ -3083,16 +3090,16 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - texres.tr= 1.0-texres.tr; - texres.tg= 1.0-texres.tg; - texres.tb= 1.0-texres.tb; + texres.tr= 1.0f-texres.tr; + texres.tg= 1.0f-texres.tg; + texres.tb= 1.0f-texres.tb; } - else texres.tin= 1.0-texres.tin; + else texres.tin= 1.0f-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgb) { @@ -3153,7 +3160,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f } } if(mtex->mapto & WOMAP_BLEND) { - if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + if(rgb) texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype); } @@ -3289,16 +3296,16 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - texres.tr= 1.0-texres.tr; - texres.tg= 1.0-texres.tg; - texres.tb= 1.0-texres.tb; + texres.tr= 1.0f-texres.tr; + texres.tg= 1.0f-texres.tg; + texres.tb= 1.0f-texres.tb; } - else texres.tin= 1.0-texres.tin; + else texres.tin= 1.0f-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgb) { @@ -3383,7 +3390,7 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output); if(rgb) { - texr.tin= (0.35*texr.tr+0.45*texr.tg+0.2*texr.tb); + texr.tin= (0.35f*texr.tr+0.45f*texr.tg+0.2f*texr.tb); } else { texr.tr= mtex->r; @@ -3432,14 +3439,14 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) tex= &imatex[shi->thread]; tex->iuser.ok= ima->ok; - texvec[0]= 0.5+0.5*suv->uv[0]; - texvec[1]= 0.5+0.5*suv->uv[1]; - texvec[2] = 0; // initalize it because imagewrap looks at it. + texvec[0]= 0.5f+0.5f*suv->uv[0]; + texvec[1]= 0.5f+0.5f*suv->uv[1]; + texvec[2] = 0.0f; // initalize it because imagewrap looks at it. if(shi->osatex) { - dx[0]= 0.5*suv->dxuv[0]; - dx[1]= 0.5*suv->dxuv[1]; - dy[0]= 0.5*suv->dyuv[0]; - dy[1]= 0.5*suv->dyuv[1]; + dx[0]= 0.5f*suv->dxuv[0]; + dx[1]= 0.5f*suv->dxuv[1]; + dy[0]= 0.5f*suv->dyuv[0]; + dy[1]= 0.5f*suv->dyuv[1]; } texr.nor= NULL; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index c08d6c0f456..b66740c87ba 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -758,7 +758,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl) if(lar->type==LA_SUN && lar->sunsky) { /* if it's sky continue and don't apply atmosphere effect on it */ - if(*zrect >= 9.9e10 || rgbrect[3]==0.0f) { + if(*zrect >= 9.9e10f || rgbrect[3]==0.0f) { continue; } @@ -1098,7 +1098,7 @@ static unsigned short *make_solid_mask(RenderPart *pa) static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask) { unsigned short shared= dmask & smask; - float mul= 1.0 - source[3]; + float mul= 1.0f - source[3]; if(shared) { /* overlapping masks */ @@ -1892,13 +1892,13 @@ static void renderflare(RenderResult *rr, float *rectf, HaloRen *har) fla.r= fabs(rc[0]); fla.g= fabs(rc[1]); fla.b= fabs(rc[2]); - fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]); - fla.hard= 20.0f + fabs(70*rc[7]); + fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]); + fla.hard= 20.0f + fabsf(70.0f*rc[7]); fla.tex= 0; - type= (int)(fabs(3.9*rc[6])); + type= (int)(fabs(3.9f*rc[6])); - fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4])); + fla.rad= ma->subsize*sqrtf(fabs(2.0f*har->rad*rc[4])); if(type==3) { fla.rad*= 3.0f; @@ -1907,22 +1907,22 @@ static void renderflare(RenderResult *rr, float *rectf, HaloRen *har) fla.radsq= fla.rad*fla.rad; - vec[0]= 1.4*rc[5]*(har->xs-R.winx/2); - vec[1]= 1.4*rc[5]*(har->ys-R.winy/2); - vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f); + vec[0]= 1.4f*rc[5]*(har->xs-R.winx/2); + vec[1]= 1.4f*rc[5]*(har->ys-R.winy/2); + vec[2]= 32.0f*sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f); - fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2]; - fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2]; + fla.xs= R.winx/2 + vec[0] + (1.2f+rc[8])*R.rectx*vec[0]/vec[2]; + fla.ys= R.winy/2 + vec[1] + (1.2f+rc[8])*R.rectx*vec[1]/vec[2]; if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) fla.ys += 0.5; - else fla.ys -= 0.5; + if(R.r.mode & R_ODDFIELD) fla.ys += 0.5f; + else fla.ys -= 0.5f; } if(type & 1) fla.type= HA_FLARECIRC; else fla.type= 0; renderhalo_post(rr, rectf, &fla); - fla.alfa*= 0.5; + fla.alfa*= 0.5f; if(type & 2) fla.type= HA_FLARECIRC; else fla.type= 0; renderhalo_post(rr, rectf, &fla); @@ -2205,7 +2205,7 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) { disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/ } else { - disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/ + disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/ } if(bs->rect_float) { @@ -2277,7 +2277,7 @@ static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3 * then taking u and v partial derivatives to get dxco and dyco */ A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]); - if(fabs(A) > FLT_EPSILON) { + if(fabsf(A) > FLT_EPSILON) { A= 0.5f/A; d1= uv2[1] - uv3[1]; @@ -2532,8 +2532,8 @@ static void shade_tface(BakeShade *bs) * where a pixel gets in between 2 faces or the middle of a quad, * camera aligned quads also have this problem but they are less common. * Add a small offset to the UVs, fixes bug #18685 - Campbell */ - vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001); - vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002); + vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001f); + vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002f); } /* UV indices have to be corrected for possible quad->tria splits */ diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 456162d2d30..0c5ad0475ab 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -943,13 +943,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f float tin, tr, tg, tb, ta; float xn, yn, zn, texvec[3], hoco[4], hoco1[4]; - if(hasize==0.0) return NULL; + if(hasize==0.0f) return NULL; projectverto(vec, re->winmat, hoco); - if(hoco[3]==0.0) return NULL; + if(hoco[3]==0.0f) return NULL; if(vec1) { projectverto(vec1, re->winmat, hoco1); - if(hoco1[3]==0.0) return NULL; + if(hoco1[3]==0.0f) return NULL; } har= RE_findOrAddHalo(obr, obr->tothalo++); @@ -959,8 +959,8 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ /* we do it here for sorting of halos */ zn= hoco[3]; - har->xs= 0.5*re->winx*(hoco[0]/zn); - har->ys= 0.5*re->winy*(hoco[1]/zn); + har->xs= 0.5f*re->winx*(hoco[0]/zn); + har->ys= 0.5f*re->winy*(hoco[1]/zn); har->zs= 0x7FFFFF*(hoco[2]/zn); har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); @@ -970,16 +970,16 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f har->type |= HA_VECT; - xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]); - yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]); - if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0; + xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]); + yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]); + if(xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0f; else zn= atan2(yn, xn); har->sin= sin(zn); har->cos= cos(zn); zn= len_v3v3(vec1, vec); - har->hasize= vectsize*zn + (1.0-vectsize)*hasize; + har->hasize= vectsize*zn + (1.0f-vectsize)*hasize; sub_v3_v3v3(har->no, vec, vec1); normalize_v3(har->no); @@ -991,7 +991,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f har->r= ma->r; har->g= ma->g; har->b= ma->b; - har->add= (255.0*ma->add); + har->add= (255.0f*ma->add); har->mat= ma; har->hard= ma->har; har->seed= seed % 256; @@ -1032,7 +1032,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, f zn= tin*mtex->alphafac; if(mtex->mapto & MAP_COL) { - zn= 1.0-yn; + zn= 1.0f-yn; har->r= (yn*tr+ zn*ma->r); har->g= (yn*tg+ zn*ma->g); har->b= (yn*tb+ zn*ma->b); @@ -1057,13 +1057,13 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3]; int i, hasrgb; - if(hasize==0.0) return NULL; + if(hasize==0.0f) return NULL; projectverto(vec, re->winmat, hoco); - if(hoco[3]==0.0) return NULL; + if(hoco[3]==0.0f) return NULL; if(vec1) { projectverto(vec1, re->winmat, hoco1); - if(hoco1[3]==0.0) return NULL; + if(hoco1[3]==0.0f) return NULL; } har= RE_findOrAddHalo(obr, obr->tothalo++); @@ -1073,8 +1073,8 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ /* we do it here for sorting of halos */ zn= hoco[3]; - har->xs= 0.5*re->winx*(hoco[0]/zn); - har->ys= 0.5*re->winy*(hoco[1]/zn); + har->xs= 0.5f*re->winx*(hoco[0]/zn); + har->ys= 0.5f*re->winy*(hoco[1]/zn); har->zs= 0x7FFFFF*(hoco[2]/zn); har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); @@ -1084,16 +1084,16 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater har->type |= HA_VECT; - xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]); - yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]); - if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0; + xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]); + yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]); + if(xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0; else zn= atan2(yn, xn); har->sin= sin(zn); har->cos= cos(zn); - zn= len_v3v3(vec1, vec)*0.5; + zn= len_v3v3(vec1, vec)*0.5f; - har->hasize= vectsize*zn + (1.0-vectsize)*hasize; + har->hasize= vectsize*zn + (1.0f-vectsize)*hasize; sub_v3_v3v3(har->no, vec, vec1); normalize_v3(har->no); @@ -1105,7 +1105,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater har->r= ma->r; har->g= ma->g; har->b= ma->b; - har->add= (255.0*ma->add); + har->add= (255.0f*ma->add); har->mat= ma; har->hard= ma->har; har->seed= seed % 256; @@ -1185,13 +1185,13 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater if(mtex->mapto & MAP_ALPHA) har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->alphafac,mtex->blendtype); if(mtex->mapto & MAP_HAR) - har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->hardfac,mtex->blendtype); + har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var,((float)har->hard)/127.0f,tin,mtex->hardfac,mtex->blendtype); if(mtex->mapto & MAP_RAYMIRR) - har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->raymirrfac,mtex->blendtype); + har->hasize = 100.0f*texture_value_blend(mtex->def_var,har->hasize/100.0f,tin,mtex->raymirrfac,mtex->blendtype); if(mtex->mapto & MAP_TRANSLU) { - float add = texture_value_blend(mtex->def_var,(float)har->add/255.0,tin,mtex->translfac,mtex->blendtype); + float add = texture_value_blend(mtex->def_var,(float)har->add/255.0f,tin,mtex->translfac,mtex->blendtype); CLAMP(add, 0.f, 1.f); - har->add = 255.0*add; + har->add = 255.0f*add; } /* now what on earth is this good for?? */ //if(mtex->texco & 16) { @@ -1270,24 +1270,24 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], projectfunc(vec, re->winmat, hoco); /* we clip halos less critical, but not for the Z */ - hoco[0]*= 0.5; - hoco[1]*= 0.5; + hoco[0]*= 0.5f; + hoco[1]*= 0.5f; if( panotestclip(re, do_pano, hoco) ) { har->miny= har->maxy= -10000; /* that way render clips it */ } - else if(hoco[3]<0.0) { + else if(hoco[3]<0.0f) { har->miny= har->maxy= -10000; /* render clips it */ } else /* do the projection...*/ { /* bring back hocos */ - hoco[0]*= 2.0; - hoco[1]*= 2.0; + hoco[0]*= 2.0f; + hoco[1]*= 2.0f; zn= hoco[3]; - har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ - har->ys= 0.5*re->winy*(1.0+hoco[1]/zn); + har->xs= 0.5f*re->winx*(1.0f+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ + har->ys= 0.5f*re->winy*(1.0f+hoco[1]/zn); /* this should be the zbuffer coordinate */ har->zs= 0x7FFFFF*(hoco[2]/zn); @@ -1298,11 +1298,11 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], projectfunc(vec, re->winmat, hoco); vec[0]-= har->hasize; zn= hoco[3]; - har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn)); + har->rad= fabsf(har->xs- 0.5f*re->winx*(1.0f+hoco[0]/zn)); /* this clip is not really OK, to prevent stars to become too large */ if(har->type & HA_ONLYSKY) { - if(har->rad>3.0) har->rad= 3.0; + if(har->rad>3.0f) har->rad= 3.0f; } har->radsq= har->rad*har->rad; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index dcb9a3063e1..5860c395b07 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -260,7 +260,7 @@ static int compress_deepsamples(DeepSample *dsample, int tot, float epsilon) } else { /* compute visibility at center between slopes at z */ - slope= (slopemin+slopemax)*0.5; + slope= (slopemin+slopemax)*0.5f; v= newds->v + slope*((z - newds->z)/(double)0x7FFFFFFF); } @@ -774,7 +774,7 @@ void makeshadowbuf(Render *re, LampRen *lar) angle= saacos(lar->spotsi); temp= 0.5f*shb->size*cos(angle)/sin(angle); shb->pixsize= (shb->d)/temp; - wsize= shb->pixsize*(shb->size/2.0); + wsize= shb->pixsize*(shb->size/2.0f); perspective_m4( shb->winmat,-wsize, wsize, -wsize, wsize, shb->d, shb->clipend); mul_m4_m4m4(shb->persmat, shb->viewmat, shb->winmat); @@ -1094,7 +1094,7 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int else { /* soft area */ temp= ( (float)(zs- zsamp) )/(float)bias; - return 1.0 - temp*temp; + return 1.0f - temp*temp; } } @@ -1287,7 +1287,7 @@ static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, i /* soft area */ temp= ( (float)(zs- zsamp) )/(float)bias; - return 1.0 - temp*temp; + return 1.0f - temp*temp; } @@ -1303,15 +1303,15 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) int x, y, z, xs1, ys1; int dx = 0, dy = 0; - siz= 0.5*(float)shb->size; + siz= 0.5f*(float)shb->size; co[0]= p1[0]; co[1]= p1[1]; co[2]= p1[2]/lar->sh_zfac; co[3]= 1.0; mul_m4_v4(shb->winmat, co); /* rational hom co */ - xf1= siz*(1.0+co[0]/co[3]); - yf1= siz*(1.0+co[1]/co[3]); + xf1= siz*(1.0f+co[0]/co[3]); + yf1= siz*(1.0f+co[1]/co[3]); zf1= (co[2]/co[3]); @@ -1320,8 +1320,8 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) co[2]= p2[2]/lar->sh_zfac; co[3]= 1.0; mul_m4_v4(shb->winmat, co); /* rational hom co */ - xf2= siz*(1.0+co[0]/co[3]); - yf2= siz*(1.0+co[1]/co[3]); + xf2= siz*(1.0f+co[0]/co[3]); + yf2= siz*(1.0f+co[1]/co[3]); zf2= (co[2]/co[3]); /* the 2dda (a pixel line formula) */ @@ -1330,8 +1330,8 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) ys1= (int)yf1; if(xf1 != xf2) { - if(xf2-xf1 > 0.0) { - labdax= (xf1-xs1-1.0)/(xf1-xf2); + if(xf2-xf1 > 0.0f) { + labdax= (xf1-xs1-1.0f)/(xf1-xf2); ldx= -shb->shadhalostep/(xf1-xf2); dx= shb->shadhalostep; } @@ -1347,8 +1347,8 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) } if(yf1 != yf2) { - if(yf2-yf1 > 0.0) { - labday= (yf1-ys1-1.0)/(yf1-yf2); + if(yf2-yf1 > 0.0f) { + labday= (yf1-ys1-1.0f)/(yf1-yf2); ldy= -shb->shadhalostep/(yf1-yf2); dy= shb->shadhalostep; } @@ -1389,16 +1389,16 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) } labda= MIN2(labdax, labday); - if(labda==labdao || labda>=1.0) break; + if(labda==labdao || labda>=1.0f) break; zf= zf1 + labda*(zf2-zf1); count+= (float)shb->totbuf; - if(zf<= -1.0) lightcount += 1.0; /* close to the spot */ + if(zf<= -1.0f) lightcount += 1.0f; /* close to the spot */ else { /* make sure, behind the clipend we extend halolines. */ - if(zf>=1.0) z= 0x7FFFF000; + if(zf>=1.0f) z= 0x7FFFF000; else z= (int)(0x7FFFF000*zf); for(shsample= shb->buffers.first; shsample; shsample= shsample->next) @@ -1407,8 +1407,8 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) } } - if(count!=0.0) return (lightcount/count); - return 0.0; + if(count!=0.0f) return (lightcount/count); + return 0.0f; } @@ -2081,11 +2081,11 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */ if(R.r.mode & R_ORTHO) { /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx= 2.0/(R.winx*R.winmat[0][0]); - float fy= 2.0/(R.winy*R.winmat[1][1]); + float fx= 2.0f/(R.winx*R.winmat[0][0]); + float fy= 2.0f/(R.winy*R.winmat[1][1]); - hoco[0]= (x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; - hoco[1]= (y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; + hoco[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; + hoco[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; /* using a*x + b*y + c*z = d equation, (a b c) is normal */ if(nor[2]!=0.0f) @@ -2141,9 +2141,9 @@ static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int f /* in osa case, the samples were filled in with factor 1.0/R.osa. if fewer samples we have to correct */ if(R.osa) - shadfacf= ((float)shadfac*R.osa)/(4096.0*samples); + shadfacf= ((float)shadfac*R.osa)/(4096.0f*samples); else - shadfacf= ((float)shadfac)/(4096.0); + shadfacf= ((float)shadfac)/(4096.0f); new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA)); new->obi= obi; @@ -2640,4 +2640,3 @@ void ISB_free(RenderPart *pa) } } } - diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index f7d1b43d4f7..0ba13b31c4b 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -172,7 +172,7 @@ static float f_Rd(float alpha_, float A, float ro) float sq; sq= sqrt(3.0f*(1.0f - alpha_)); - return (alpha_/2.0f)*(1.0f + exp((-4.0f/3.0f)*A*sq))*exp(-sq) - ro; + return (alpha_/2.0f)*(1.0f + expf((-4.0f/3.0f)*A*sq))*expf(-sq) - ro; } static float compute_reduced_albedo(ScatterSettings *ss) @@ -189,10 +189,10 @@ static float compute_reduced_albedo(ScatterSettings *ss) for(i= 0; i < max_iteration_count; i++) { fsub= (fxn - fxn_1); - if(fabs(fsub) < tolerance) + if(fabsf(fsub) < tolerance) break; d= ((xn - xn_1)/fsub)*fxn; - if(fabs(d) < tolerance) + if(fabsf(d) < tolerance) break; xn_1= xn; @@ -221,10 +221,10 @@ static float Rd_rsquare(ScatterSettings *ss, float rr) sr= sqrt(rr + ss->zr*ss->zr); sv= sqrt(rr + ss->zv*ss->zv); - Rdr= ss->zr*(1.0f + ss->sigma*sr)*exp(-ss->sigma*sr)/(sr*sr*sr); - Rdv= ss->zv*(1.0f + ss->sigma*sv)*exp(-ss->sigma*sv)/(sv*sv*sv); + Rdr= ss->zr*(1.0f + ss->sigma*sr)*expf(-ss->sigma*sr)/(sr*sr*sr); + Rdv= ss->zv*(1.0f + ss->sigma*sv)*expf(-ss->sigma*sv)/(sv*sv*sv); - return /*ss->alpha_*/(1.0f/(4.0f*M_PI))*(Rdr + Rdv); + return /*ss->alpha_*/(1.0f/(4.0f*(float)M_PI))*(Rdr + Rdv); } static float Rd(ScatterSettings *ss, float r) @@ -316,7 +316,7 @@ ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float ss->alpha_= compute_reduced_albedo(ss); ss->sigma= 1.0f/ss->ld; - ss->sigma_t_= ss->sigma/sqrt(3.0f*(1.0f - ss->alpha_)); + ss->sigma_t_= ss->sigma/sqrtf(3.0f*(1.0f - ss->alpha_)); ss->sigma_s_= ss->alpha_*ss->sigma_t_; ss->sigma_a= ss->sigma_t_ - ss->sigma_s_; @@ -489,7 +489,7 @@ static void sum_leaf_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) for(i=0; i<node->totpoint; i++) { p= &node->points[i]; - rad= p->area*fabs(p->rad[0] + p->rad[1] + p->rad[2]); + rad= p->area*fabsf(p->rad[0] + p->rad[1] + p->rad[2]); totrad += rad; node->co[0] += rad*p->co[0]; @@ -513,20 +513,20 @@ static void sum_leaf_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) } if(node->area > 1e-16f) { - inv= 1.0/node->area; + inv= 1.0f/node->area; node->rad[0] *= inv; node->rad[1] *= inv; node->rad[2] *= inv; } if(node->backarea > 1e-16f) { - inv= 1.0/node->backarea; + inv= 1.0f/node->backarea; node->backrad[0] *= inv; node->backrad[1] *= inv; node->backrad[2] *= inv; } if(totrad > 1e-16f) { - inv= 1.0/totrad; + inv= 1.0f/totrad; node->co[0] *= inv; node->co[1] *= inv; node->co[2] *= inv; @@ -566,8 +566,8 @@ static void sum_branch_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) subnode= node->child[i]; - rad= subnode->area*fabs(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]); - rad += subnode->backarea*fabs(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]); + rad= subnode->area*fabsf(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]); + rad += subnode->backarea*fabsf(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]); totrad += rad; node->co[0] += rad*subnode->co[0]; @@ -587,20 +587,20 @@ static void sum_branch_radiance(ScatterTree *UNUSED(tree), ScatterNode *node) } if(node->area > 1e-16f) { - inv= 1.0/node->area; + inv= 1.0f/node->area; node->rad[0] *= inv; node->rad[1] *= inv; node->rad[2] *= inv; } if(node->backarea > 1e-16f) { - inv= 1.0/node->backarea; + inv= 1.0f/node->backarea; node->backrad[0] *= inv; node->backrad[1] *= inv; node->backrad[2] *= inv; } if(totrad > 1e-16f) { - inv= 1.0/totrad; + inv= 1.0f/totrad; node->co[0] *= inv; node->co[1] *= inv; node->co[2] *= inv; @@ -668,9 +668,9 @@ static void create_octree_node(ScatterTree *tree, ScatterNode *node, float *mid, return; } - subsize[0]= size[0]*0.5; - subsize[1]= size[1]*0.5; - subsize[2]= size[2]*0.5; + subsize[0]= size[0]*0.5f; + subsize[1]= size[1]*0.5f; + subsize[2]= size[2]*0.5f; node->split[0]= mid[0]; node->split[1]= mid[1]; @@ -764,7 +764,7 @@ ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error, for(i=0; i<totpoint; i++) { VECCOPY(points[i].co, co[i]); VECCOPY(points[i].rad, color[i]); - points[i].area= fabs(area[i])/(tree->scale*tree->scale); + points[i].area= fabsf(area[i])/(tree->scale*tree->scale); points[i].back= (area[i] < 0.0f); mul_v3_fl(points[i].co, 1.0f/tree->scale); @@ -794,13 +794,13 @@ void scatter_tree_build(ScatterTree *tree) tree->root->points= newpoints; tree->root->totpoint= totpoint; - mid[0]= (tree->min[0]+tree->max[0])*0.5; - mid[1]= (tree->min[1]+tree->max[1])*0.5; - mid[2]= (tree->min[2]+tree->max[2])*0.5; + mid[0]= (tree->min[0]+tree->max[0])*0.5f; + mid[1]= (tree->min[1]+tree->max[1])*0.5f; + mid[2]= (tree->min[2]+tree->max[2])*0.5f; - size[0]= (tree->max[0]-tree->min[0])*0.5; - size[1]= (tree->max[1]-tree->min[1])*0.5; - size[2]= (tree->max[2]-tree->min[2])*0.5; + size[0]= (tree->max[0]-tree->min[0])*0.5f; + size[1]= (tree->max[1]-tree->min[1])*0.5f; + size[2]= (tree->max[2]-tree->min[2])*0.5f; create_octree_node(tree, tree->root, mid, size, tree->refpoints, 0); diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 72cb35e7827..840e5444ff0 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -78,9 +78,9 @@ static float strand_eval_width(Material *ma, float strandco) if(ma->strand_ease!=0.0f) { if(ma->strand_ease<0.0f) - fac= pow(strandco, 1.0+ma->strand_ease); + fac= pow(strandco, 1.0f+ma->strand_ease); else - fac= pow(strandco, 1.0/(1.0f-ma->strand_ease)); + fac= pow(strandco, 1.0f/(1.0f-ma->strand_ease)); } else fac= strandco; @@ -816,8 +816,8 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop); /* needed for transform from hoco to zbuffer co */ - zspan.zmulx= ((float)winx)/2.0; - zspan.zmuly= ((float)winy)/2.0; + zspan.zmulx= ((float)winx)/2.0f; + zspan.zmuly= ((float)winy)/2.0f; zspan.zofsx= -pa->disprect.xmin; zspan.zofsy= -pa->disprect.ymin; diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index 5877fa42292..e824b81096b 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -68,12 +68,12 @@ * */ void ClipColor(float c[3]) { - if (c[0] > 1.0) c[0] = 1.0; - if (c[0] < 0.0) c[0] = 0.0; - if (c[1] > 1.0) c[1] = 1.0; - if (c[1] < 0.0) c[1] = 0.0; - if (c[2] > 1.0) c[2] = 1.0; - if (c[2] < 0.0) c[2] = 0.0; + if (c[0] > 1.0f) c[0] = 1.0f; + if (c[0] < 0.0f) c[0] = 0.0f; + if (c[1] > 1.0f) c[1] = 1.0f; + if (c[1] < 0.0f) c[1] = 0.0f; + if (c[2] > 1.0f) c[2] = 1.0f; + if (c[2] < 0.0f) c[2] = 0.0f; } /** @@ -85,9 +85,9 @@ static float AngleBetween(float thetav, float phiv, float theta, float phi) { float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta); - if (cospsi > 1.0) + if (cospsi > 1.0f) return 0; - if (cospsi < -1.0) + if (cospsi < -1.0f) return M_PI; return acos(cospsi); @@ -117,11 +117,11 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, { float den, num; - den = ((1 + lam[0] * exp(lam[1])) * - (1 + lam[2] * exp(lam[3] * sunsky->theta) + lam[4] * cos(sunsky->theta) * cos(sunsky->theta))); + den = ((1 + lam[0] * expf(lam[1])) * + (1 + lam[2] * expf(lam[3] * sunsky->theta) + lam[4] * cosf(sunsky->theta) * cosf(sunsky->theta))); - num = ((1 + lam[0] * exp(lam[1] / cos(theta))) * - (1 + lam[2] * exp(lam[3] * gamma) + lam[4] * cos(gamma) * cos(gamma))); + num = ((1 + lam[0] * expf(lam[1] / cosf(theta))) * + (1 + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma))); return(lvz * num / den);} @@ -173,41 +173,41 @@ void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_b T = turb; T2 = turb*turb; - chi = (4.0 / 9.0 - T / 120.0) * (M_PI - 2 * sunsky->theta); - sunsky->zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - .2155 * T + 2.4192; + chi = (4.0f / 9.0f - T / 120.0f) * ((float)M_PI - 2.0f * sunsky->theta); + sunsky->zenith_Y = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f; sunsky->zenith_Y *= 1000; // conversion from kcd/m^2 to cd/m^2 if (sunsky->zenith_Y<=0) sunsky->zenith_Y = 1e-6; sunsky->zenith_x = - ( + 0.00165 * theta3 - 0.00374 * theta2 + 0.00208 * sunsky->theta + 0) * T2 + - ( -0.02902 * theta3 + 0.06377 * theta2 - 0.03202 * sunsky->theta + 0.00394) * T + - ( + 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * sunsky->theta + 0.25885); + ( + 0.00165f * theta3 - 0.00374f * theta2 + 0.00208f * sunsky->theta + 0.0f) * T2 + + ( -0.02902f * theta3 + 0.06377f * theta2 - 0.03202f * sunsky->theta + 0.00394f) * T + + ( + 0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * sunsky->theta + 0.25885f); sunsky->zenith_y = - ( + 0.00275 * theta3 - 0.00610 * theta2 + 0.00316 * sunsky->theta + 0) * T2 + - ( -0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * sunsky->theta + 0.00515) * T + - ( + 0.15346 * theta3 - 0.26756 * theta2 + 0.06669 * sunsky->theta + 0.26688); + ( + 0.00275f * theta3 - 0.00610f * theta2 + 0.00316f * sunsky->theta + 0.0f) * T2 + + ( -0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * sunsky->theta + 0.00515f) * T + + ( + 0.15346f * theta3 - 0.26756f * theta2 + 0.06669f * sunsky->theta + 0.26688f); - sunsky->perez_Y[0] = 0.17872 * T - 1.46303; - sunsky->perez_Y[1] = -0.35540 * T + 0.42749; - sunsky->perez_Y[2] = -0.02266 * T + 5.32505; - sunsky->perez_Y[3] = 0.12064 * T - 2.57705; - sunsky->perez_Y[4] = -0.06696 * T + 0.37027; - - sunsky->perez_x[0] = -0.01925 * T - 0.25922; - sunsky->perez_x[1] = -0.06651 * T + 0.00081; - sunsky->perez_x[2] = -0.00041 * T + 0.21247; - sunsky->perez_x[3] = -0.06409 * T - 0.89887; - sunsky->perez_x[4] = -0.00325 * T + 0.04517; - - sunsky->perez_y[0] = -0.01669 * T - 0.26078; - sunsky->perez_y[1] = -0.09495 * T + 0.00921; - sunsky->perez_y[2] = -0.00792 * T + 0.21023; - sunsky->perez_y[3] = -0.04405 * T - 1.65369; - sunsky->perez_y[4] = -0.01092 * T + 0.05291; + sunsky->perez_Y[0] = 0.17872f * T - 1.46303f; + sunsky->perez_Y[1] = -0.35540f * T + 0.42749f; + sunsky->perez_Y[2] = -0.02266f * T + 5.32505f; + sunsky->perez_Y[3] = 0.12064f * T - 2.57705f; + sunsky->perez_Y[4] = -0.06696f * T + 0.37027f; + + sunsky->perez_x[0] = -0.01925f * T - 0.25922f; + sunsky->perez_x[1] = -0.06651f * T + 0.00081f; + sunsky->perez_x[2] = -0.00041f * T + 0.21247f; + sunsky->perez_x[3] = -0.06409f * T - 0.89887f; + sunsky->perez_x[4] = -0.00325f * T + 0.04517f; + + sunsky->perez_y[0] = -0.01669f * T - 0.26078f; + sunsky->perez_y[1] = -0.09495f * T + 0.00921f; + sunsky->perez_y[2] = -0.00792f * T + 0.21023f; + sunsky->perez_y[3] = -0.04405f * T - 1.65369f; + sunsky->perez_y[4] = -0.01092f * T + 0.05291f; /* suggested by glome in * http://projects.blender.org/tracker/?func=detail&atid=127&aid=8063&group_id=9*/ @@ -248,17 +248,17 @@ void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float colo float hfade=1, nfade=1; - if (theta>(0.5*M_PI)) { - hfade = 1.0-(theta*M_1_PI-0.5)*2.0; - hfade = hfade*hfade*(3.0-2.0*hfade); + if (theta>(0.5f*(float)M_PI)) { + hfade = 1.0f-(theta*(float)M_1_PI-0.5f)*2.0f; + hfade = hfade*hfade*(3.0f-2.0f*hfade); theta = 0.5*M_PI; } - if (sunsky->theta>(0.5*M_PI)) { - if (theta<=0.5*M_PI) { - nfade = 1.0-(0.5-theta*M_1_PI)*2.0; - nfade *= 1.0-(sunsky->theta*M_1_PI-0.5)*2.0; - nfade = nfade*nfade*(3.0-2.0*nfade); + if (sunsky->theta>(0.5f*(float)M_PI)) { + if (theta<=0.5f*(float)M_PI) { + nfade = 1.0f-(0.5f-theta*(float)M_1_PI)*2.0f; + nfade *= 1.0f-(sunsky->theta*(float)M_1_PI-0.5f)*2.0f; + nfade = nfade*nfade*(3.0f-2.0f*nfade); } } @@ -267,7 +267,7 @@ void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float colo // Compute xyY values x = PerezFunction(sunsky, sunsky->perez_x, theta, gamma, sunsky->zenith_x); y = PerezFunction(sunsky, sunsky->perez_y, theta, gamma, sunsky->zenith_y); - Y = 6.666666667e-5 * nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y); + Y = 6.666666667e-5f * nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y); if(sunsky->sky_exposure!=0.0f) Y = 1.0 - exp(Y*sunsky->sky_exposure); @@ -296,8 +296,8 @@ void GetSkyXYZRadiancef(struct SunSky* sunsky, const float varg[3], float color_ copy_v3_v3(v, (float*)varg); normalize_v3(v); - if (v[2] < 0.001){ - v[2] = 0.001; + if (v[2] < 0.001f) { + v[2] = 0.001f; normalize_v3(v); } @@ -329,15 +329,15 @@ static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3]) fAlpha = 1.3f; fBeta = 0.04608365822050f * turbidity - 0.04586025928522f; - m = 1.0/(cos(theta) + 0.15f*pow(93.885f-theta/M_PI*180.0f,-1.253f)); + m = 1.0f/(cosf(theta) + 0.15f*powf(93.885f-theta/(float)M_PI*180.0f,-1.253f)); for(i = 0; i < 3; i++) { // Rayleigh Scattering - fTauR = exp( -m * 0.008735f * pow(fLambda[i], (float)(-4.08f))); + fTauR = expf( -m * 0.008735f * powf(fLambda[i], (float)(-4.08f))); // Aerosal (water + dust) attenuation - fTauA = exp(-m * fBeta * pow(fLambda[i], -fAlpha)); + fTauA = exp(-m * fBeta * powf(fLambda[i], -fAlpha)); fTau[i] = fTauR * fTauA; } @@ -364,8 +364,8 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r const float pn = 0.035f; const float T = 2.0f; float fTemp, fTemp2, fTemp3, fBeta, fBetaDash; - float c = (6.544*T - 6.51)*1e-17; - float K[3] = {0.685f, 0.679f, 0.670f}; + float c = (6.544f*T - 6.51f)*1e-17f; + float K[3] = {0.685f, 0.679f, 0.670f}; float vBetaMieTemp[3]; float fLambda[3],fLambda2[3], fLambda4[3]; @@ -410,7 +410,7 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r // Mie scattering constants. - fTemp2 = 0.434*c*(2*pi)*(2*pi)*0.5f; + fTemp2 = 0.434f*c*(2*pi)*(2*pi)*0.5f; vec3opf(sunSky->atm_BetaDashMie, vLambda2, *, fTemp2); fTemp3 = 0.434f*c*pi*(2*pi)*(2*pi); @@ -460,7 +460,7 @@ void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float vec3opv(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie); //e^(-(beta_1 + beta_2) * s) = E1 - vec3opf(E1, sunSky->atm_BetaRM, *, -s/M_LN2); + vec3opf(E1, sunSky->atm_BetaRM, *, -s/(float)M_LN2); E1[0] = exp(E1[0]); E1[1] = exp(E1[1]); E1[2] = exp(E1[2]); @@ -469,17 +469,17 @@ void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float //Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2) fTemp = 1 + sunSky->atm_HGg - 2 * sunSky->atm_HGg * costheta; - fTemp = fTemp * sqrt(fTemp); + fTemp = fTemp * sqrtf(fTemp); Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg)/fTemp; vec3opf(vTemp1, sunSky->atm_BetaDashRay, *, Phase_1); vec3opf(vTemp2, sunSky->atm_BetaDashMie, *, Phase_2); vec3opv(vTemp1, vTemp1, +, vTemp2); - fopvec3(vTemp2, 1.0, -, E1); + fopvec3(vTemp2, 1.0f, -, E1); vec3opv(vTemp1, vTemp1, *, vTemp2); - fopvec3(vTemp2, 1.0, / , sunSky->atm_BetaRM); + fopvec3(vTemp2, 1.0f, / , sunSky->atm_BetaRM); vec3opv(I, vTemp1, *, vTemp2); diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index faa915b7f6c..2037acc943f 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -400,7 +400,7 @@ static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Materi sb[j] += vp->data_b[i]; /* Displays progress every second */ - if(time-lasttime>1.0f) { + if(time-lasttime>1.0) { char str[64]; BLI_snprintf(str, sizeof(str), "Simulating multiple scattering: %d%%", (int)(100.0f * (c / total))); re->i.infostr= str; @@ -747,7 +747,7 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o caching=0; time= PIL_check_seconds_timer(); - if(time-lasttime>1.0f) { + if(time-lasttime>1.0) { char str[64]; BLI_snprintf(str, sizeof(str), "Precaching volume: %d%%", (int)(100.0f * ((float)counter / (float)totparts))); re->i.infostr= str; diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 359002d05ae..19bbb11e143 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -422,9 +422,9 @@ static void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize tau[1] += stepd * sigma_t[1]; tau[2] += stepd * sigma_t[2]; - tr[0] *= exp(-tau[0]); - tr[1] *= exp(-tau[1]); - tr[2] *= exp(-tau[2]); + tr[0] *= expf(-tau[0]); + tr[1] *= expf(-tau[1]); + tr[2] *= expf(-tau[2]); } /* Compute transmittance = e^(-attenuation) */ @@ -473,7 +473,7 @@ static void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return; if ((lar->lay & shi->lay)==0) return; - if (lar->energy == 0.0) return; + if (lar->energy == 0.0f) return; if ((visifac= lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return; @@ -613,7 +613,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float /* transmittance component (alpha) */ vol_get_transmittance_seg(shi, tr, stepsize, co, density); - if (t0 > t1 * 0.25) { + if (t0 > t1 * 0.25f) { /* only use depth cutoff after we've traced a little way into the volume */ if (luminance(tr) < shi->mat->vol.depth_cutoff) break; } @@ -623,9 +623,9 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float if (shi->obi->volume_precache) { float p2[3]; - p2[0] = p[0] + (step_vec[0] * 0.5); - p2[1] = p[1] + (step_vec[1] * 0.5); - p2[2] = p[2] + (step_vec[2] * 0.5); + p2[0] = p[0] + (step_vec[0] * 0.5f); + p2[1] = p[1] + (step_vec[1] * 0.5f); + p2[2] = p[2] + (step_vec[2] * 0.5f); vol_get_precached_scattering(&R, shi, scatter_col, p2); } else @@ -817,7 +817,7 @@ void shade_volume_inside(ShadeInput *shi, ShadeResult *shr) volume_trace(shi, shr, VOL_SHADE_INSIDE); shr->alpha = shr->alpha + prev_alpha; - CLAMP(shr->alpha, 0.0, 1.0); + CLAMP(shr->alpha, 0.0f, 1.0f); shi->mat = mat_backup; shi->obi = obi_backup; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 693eb4a9893..3ef70d703a5 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -413,9 +413,9 @@ int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) } case TEX_REPEAT: { - co[0] = co[0] - floor(co[0]); - co[1] = co[1] - floor(co[1]); - co[2] = co[2] - floor(co[2]); + co[0] = co[0] - floorf(co[0]); + co[1] = co[1] - floorf(co[1]); + co[2] = co[2] - floorf(co[2]); break; } case TEX_EXTEND: diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 13d9ead79e8..04e4ce2c647 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -217,24 +217,24 @@ static short cliptestf(float p, float q, float *u1, float *u2) { float r; - if(p<0.0) { + if(p<0.0f) { if(q<p) return 0; - else if(q<0.0) { + else if(q<0.0f) { r= q/p; if(r>*u2) return 0; else if(r>*u1) *u1=r; } } else { - if(p>0.0) { - if(q<0.0) return 0; + if(p>0.0f) { + if(q<0.0f) return 0; else if(q<p) { r= q/p; if(r<*u1) return 0; else if(r<*u2) *u2=r; } } - else if(q<0.0) return 0; + else if(q<0.0f) return 0; } return 1; } @@ -344,7 +344,7 @@ static void zbuffillAc4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, y0= z1*x2-x1*z2; z0= x1*y2-y1*x2; - if(z0==0.0) return; + if(z0==0.0f) return; xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; @@ -859,8 +859,8 @@ static int clipline(float *v1, float *v2) /* return 0: do not draw */ if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) { dx= v2[0]-v1[0]; - dz= 1.01*(v2[3]-v1[3]); - v13= 1.01*v1[3]; + dz= 1.01f*(v2[3]-v1[3]); + v13= 1.01f*v1[3]; if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) { if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) { @@ -870,13 +870,13 @@ static int clipline(float *v1, float *v2) /* return 0: do not draw */ if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) { if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) { - if(u2<1.0) { + if(u2<1.0f) { v2[0]= v1[0]+u2*dx; v2[1]= v1[1]+u2*dy; v2[2]= v1[2]+u2*dz; v2[3]= v1[3]+u2*dw; } - if(u1>0.0) { + if(u1>0.0f) { v1[0]= v1[0]+u1*dx; v1[1]= v1[1]+u1*dy; v1[2]= v1[2]+u1*dz; @@ -898,8 +898,8 @@ void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco) float div; div= 1.0f/hoco[3]; - zco[0]= zspan->zmulx*(1.0+hoco[0]*div) + zspan->zofsx; - zco[1]= zspan->zmuly*(1.0+hoco[1]*div) + zspan->zofsy; + zco[0]= zspan->zmulx*(1.0f+hoco[0]*div) + zspan->zofsx; + zco[1]= zspan->zmuly*(1.0f+hoco[1]*div) + zspan->zofsy; zco[2]= 0x7FFFFFFF *(hoco[2]*div); } @@ -1083,7 +1083,7 @@ static void zbuffillGLinv4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v y0= z1*x2-x1*z2; z0= x1*y2-y1*x2; - if(z0==0.0) return; + if(z0==0.0f) return; xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; @@ -1203,7 +1203,7 @@ static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, y0= z1*x2-x1*z2; z0= x1*y2-y1*x2; - if(z0==0.0) return; + if(z0==0.0f) return; xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; @@ -1330,7 +1330,7 @@ static void zbuffillGL_onlyZ(ZSpan *zspan, int UNUSED(obi), int UNUSED(zvlnr), f y0= z1*x2-x1*z2; z0= x1*y2-y1*x2; - if(z0==0.0) return; + if(z0==0.0f) return; xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; @@ -1627,12 +1627,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a if(cliptestf(-da-dw, v13+v1[a], &u1,&u2)) { if(cliptestf(da-dw, v13-v1[a], &u1,&u2)) { *b3=1; - if(u2<1.0) { + if(u2<1.0f) { labda[1]= u2; *b2=1; } else labda[1]=1.0; /* u2 */ - if(u1>0.0) { + if(u1>0.0f) { labda[0]= u1; *b2=1; } else labda[0]=0.0; @@ -1662,8 +1662,8 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo l1= labda[0]; l2= labda[1]; - if(l1!= -1.0) { - if(l1!= 0.0) { + if(l1!= -1.0f) { + if(l1!= 0.0f) { adr= vez+4*(*clve); trias[*b1]=adr; (*clve)++; @@ -1676,8 +1676,8 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo (*b1)++; } - if(l2!= -1.0) { - if(l2!= 1.0) { + if(l2!= -1.0f) { + if(l2!= 1.0f) { adr= vez+4*(*clve); trias[*b1]=adr; (*clve)++; @@ -2066,8 +2066,8 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop); /* needed for transform from hoco to zbuffer co */ - zspan->zmulx= ((float)R.winx)/2.0; - zspan->zmuly= ((float)R.winy)/2.0; + zspan->zmulx= ((float)R.winx)/2.0f; + zspan->zmuly= ((float)R.winy)/2.0f; if(R.osa) { zspan->zofsx= -pa->disprect.xmin - R.jit[pa->sample+zsample][0]; @@ -2290,8 +2290,8 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int /* 1.0f for clipping in clippyra()... bad stuff actually */ zbuf_alloc_span(&zspan, size, size, 1.0f); - zspan.zmulx= ((float)size)/2.0; - zspan.zmuly= ((float)size)/2.0; + zspan.zmulx= ((float)size)/2.0f; + zspan.zmuly= ((float)size)/2.0f; /* -0.5f to center the sample position */ zspan.zofsx= jitx - 0.5f; zspan.zofsy= jity - 0.5f; @@ -2527,8 +2527,8 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo zspan.sss_func= func; /* needed for transform from hoco to zbuffer co */ - zspan.zmulx= ((float)R.winx)/2.0; - zspan.zmuly= ((float)R.winy)/2.0; + zspan.zmulx= ((float)R.winx)/2.0f; + zspan.zmuly= ((float)R.winy)/2.0f; /* -0.5f to center the sample position */ zspan.zofsx= -pa->disprect.xmin - 0.5f; @@ -2671,7 +2671,7 @@ static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float y0= z1*x2-x1*z2; z0= x1*y2-y1*x2; - if(z0==0.0) return; + if(z0==0.0f) return; xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; @@ -2840,8 +2840,8 @@ static void quad_bezier_2d(float *result, float *v1, float *v2, float *ipodata) p1[1]= v1[1]; /* official formula 2*p2 - .5*p1 - .5*p3 */ - p2[0]= -0.5*p1[0] - 0.5*p3[0]; - p2[1]= -0.5*p1[1] - 0.5*p3[1]; + p2[0]= -0.5f*p1[0] - 0.5f*p3[0]; + p2[1]= -0.5f*p1[1] - 0.5f*p3[1]; result[0]= ipodata[0]*p1[0] + ipodata[1]*p2[0] + ipodata[2]*p3[0]; result[1]= ipodata[0]*p1[1] + ipodata[1]*p2[1] + ipodata[2]*p3[1]; @@ -2871,8 +2871,8 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float * char *rectmove, *dm; zbuf_alloc_span(&zspan, xsize, ysize, 1.0f); - zspan.zmulx= ((float)xsize)/2.0; - zspan.zmuly= ((float)ysize)/2.0; + zspan.zmulx= ((float)xsize)/2.0f; + zspan.zmuly= ((float)ysize)/2.0f; zspan.zofsx= 0.0f; zspan.zofsy= 0.0f; @@ -3258,8 +3258,8 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * zbuf_alloc_span(zspan, pa->rectx, pa->recty, re->clipcrop); /* needed for transform from hoco to zbuffer co */ - zspan->zmulx= ((float)winx)/2.0; - zspan->zmuly= ((float)winy)/2.0; + zspan->zmulx= ((float)winx)/2.0f; + zspan->zmuly= ((float)winy)/2.0f; /* the buffers */ zspan->arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz"); @@ -3344,15 +3344,15 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * if(partclip==0) { /* a little advantage for transp rendering (a z offset) */ - if(!shadow && ma->zoffs != 0.0) { + if(!shadow && ma->zoffs != 0.0f) { mul= 0x7FFFFFFF; - zval= mul*(1.0+ho1[2]/ho1[3]); + zval= mul*(1.0f+ho1[2]/ho1[3]); VECCOPY(vec, v1->co); /* z is negative, otherwise its being clipped */ vec[2]-= ma->zoffs; projectverto(vec, obwinmat, hoco); - fval= mul*(1.0+hoco[2]/hoco[3]); + fval= mul*(1.0f+hoco[2]/hoco[3]); polygon_offset= (int) fabs(zval - fval ); } @@ -4240,7 +4240,3 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas /* end of zbuf.c */ - - - - diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 20ac3ba7077..dc83e29b497 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -67,6 +67,7 @@ set(SRC intern/wm_window.c WM_api.h + WM_keymap.h WM_types.h wm.h wm_cursors.h diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index 5b6e8b1ab30..e548d99e9a5 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -26,7 +26,7 @@ if env['WITH_BF_PYTHON']: if env['WITH_BF_COLLADA']: defs.append('WITH_COLLADA') -if env['OURPLATFORM'] == 'linux2': +if env['OURPLATFORM'] == 'linux': cflags='-pthread' incs += ' ../../../extern/binreloc/include' diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e6325e2101a..e1b8cefca4b 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -41,6 +41,7 @@ /* dna-savable wmStructs here */ #include "DNA_windowmanager_types.h" +#include "WM_keymap.h" #ifdef __cplusplus extern "C" { @@ -114,50 +115,9 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); void WM_cursor_warp (struct wmWindow *win, int x, int y); - /* keyconfig and keymap */ -wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname); -wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname); -void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); -void WM_keyconfig_free (struct wmKeyConfig *keyconf); -void WM_keyconfig_userdef(void); - -void WM_keymap_init (struct bContext *C); -void WM_keymap_free (struct wmKeyMap *keymap); - -wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); -wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); -wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type, - int val, int modifier, int keymodifier); - -void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); -char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); - -wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid); -wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); -wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); -int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap); -wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *keymap); -void WM_keymap_restore_to_default(struct wmKeyMap *keymap); -void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties); -void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); - -wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id); -int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); + /* event map */ int WM_userdef_event_map(int kmitype); -wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); -wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); -wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); -void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); - -const char *WM_key_event_string(short type); -int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r); -char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); - /* handlers */ struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap); @@ -219,7 +179,7 @@ void WM_operator_free (struct wmOperator *op); void WM_operator_stack_clear(struct wmWindowManager *wm); struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet); -struct wmOperatorType *WM_operatortype_first(void); +struct GHashIterator *WM_operatortype_iter(void); void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*)); void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); @@ -262,6 +222,7 @@ wmOperator *WM_operator_last_redo(const struct bContext *C); #define WM_FILESEL_DIRECTORY (1 << 1) #define WM_FILESEL_FILENAME (1 << 2) #define WM_FILESEL_FILEPATH (1 << 3) +#define WM_FILESEL_FILES (1 << 4) /* operator as a python command (resultuing string must be free'd) */ @@ -270,6 +231,7 @@ void WM_operator_bl_idname(char *to, const char *from); void WM_operator_py_idname(char *to, const char *from); /* *************** menu types ******************** */ +void WM_menutype_init(void); struct MenuType *WM_menutype_find(const char *idname, int quiet); int WM_menutype_add(struct MenuType* mt); int WM_menutype_contains(struct MenuType* mt); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h new file mode 100644 index 00000000000..e00cd288c9a --- /dev/null +++ b/source/blender/windowmanager/WM_keymap.h @@ -0,0 +1,104 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef WM_KEYMAP_H +#define WM_KEYMAP_H + +/** \file WM_keymap.h + * \ingroup wm + */ + +/* dna-savable wmStructs here */ +#include "DNA_windowmanager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct EnumPropertyItem; + +/* Key Configuration */ + +wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname); +wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname); +void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); +void WM_keyconfig_free (struct wmKeyConfig *keyconf); + +void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname); + +void WM_keyconfig_update(struct wmWindowManager *wm); +void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); + +/* Keymap */ + +void WM_keymap_init (struct bContext *C); +void WM_keymap_free (struct wmKeyMap *keymap); + +wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); +wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); +wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type, + int val, int modifier, int keymodifier); + +void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); +char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); + +wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid); +wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); +wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); + +wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id); +int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); + +/* Modal Keymap */ + +wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); +wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); +wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); +void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); + +/* Keymap Editor */ + +void WM_keymap_restore_to_default(struct wmKeyMap *keymap, struct bContext *C); +void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties); +void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); + +/* Key Event */ + +const char *WM_key_event_string(short type); +int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r); +char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len); + +#ifdef __cplusplus +} +#endif + +#endif /* WM_KEYMAP_H */ + diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 7fd52e89a5f..cc3ae3ab753 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -389,8 +389,14 @@ typedef struct wmNDOFMotionData { /* awfully similar to GHOST_TEventNDOFMotionData... */ // Each component normally ranges from -1 to +1, but can exceed that. // These use blender standard view coordinates, with positive rotations being CCW about the axis. - float tvec[3]; // translation - float rvec[3]; // rotation: + union { + float tvec[3]; // translation + struct { float tx, ty, tz; }; + }; + union { + float rvec[3]; // rotation: + struct { float rx, ry, rz; }; + }; // axis = (rx,ry,rz).normalized // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] float dt; // time since previous NDOF Motion event @@ -417,8 +423,6 @@ typedef struct wmTimer { typedef struct wmOperatorType { - struct wmOperatorType *next, *prev; - const char *name; /* text for ui, undo */ const char *idname; /* unique identifier */ const char *description; /* tooltips and python docs */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index a535c0bc1f8..9299b50103c 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -40,7 +40,11 @@ #include "GHOST_C-api.h" +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BKE_blender.h" #include "BKE_context.h" @@ -59,8 +63,6 @@ #include "wm_draw.h" #include "wm.h" -#include "MEM_guardedalloc.h" - #include "ED_screen.h" #ifdef WITH_PYTHON @@ -151,14 +153,14 @@ void WM_operator_stack_clear(wmWindowManager *wm) /* ****************************************** */ -static ListBase menutypes = {NULL, NULL}; /* global menutype list */ +static GHash *menutypes_hash= NULL; MenuType *WM_menutype_find(const char *idname, int quiet) { MenuType* mt; if (idname[0]) { - mt= BLI_findstring(&menutypes, idname, offsetof(MenuType, idname)); + mt= BLI_ghash_lookup(menutypes_hash, idname); if(mt) return mt; } @@ -171,35 +173,55 @@ MenuType *WM_menutype_find(const char *idname, int quiet) int WM_menutype_add(MenuType* mt) { - BLI_addtail(&menutypes, mt); + BLI_ghash_insert(menutypes_hash, (void *)mt->idname, mt); return 1; } /* inefficient but only used for tooltip code */ int WM_menutype_contains(MenuType* mt) { - return (mt != NULL && BLI_findindex(&menutypes, mt) != -1); + int found= FALSE; + + if(mt) { + GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash); + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + if(mt == BLI_ghashIterator_getValue(iter)) { + found= TRUE; + break; + } + } + BLI_ghashIterator_free(iter); + } + + return found; } void WM_menutype_freelink(MenuType* mt) { - BLI_freelinkN(&menutypes, mt); + BLI_ghash_remove(menutypes_hash, mt->idname, NULL, (GHashValFreeFP)MEM_freeN); } -void WM_menutype_free(void) +/* called on initialize WM_init() */ +void WM_menutype_init(void) { - MenuType* mt= menutypes.first, *mt_next; + menutypes_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "menutypes_hash gh"); +} - while(mt) { - mt_next= mt->next; +void WM_menutype_free(void) +{ + GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash); - if(mt->ext.free) + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + MenuType *mt= BLI_ghashIterator_getValue(iter); + if(mt->ext.free) { mt->ext.free(mt->ext.data); - - WM_menutype_freelink(mt); - - mt= mt_next; + } } + BLI_ghashIterator_free(iter); + + BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN); + menutypes_hash= NULL; } /* ****************************************** */ @@ -210,12 +232,18 @@ void WM_keymap_init(bContext *C) if(!wm->defaultconf) wm->defaultconf= WM_keyconfig_new(wm, "Blender"); + if(!wm->addonconf) + wm->addonconf= WM_keyconfig_new(wm, "Blender Addon"); + if(!wm->userconf) + wm->userconf= WM_keyconfig_new(wm, "Blender User"); - if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { + if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { /* create default key config */ wm_window_keymap(wm->defaultconf); ED_spacetypes_keymap(wm->defaultconf); - WM_keyconfig_userdef(); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); wm->initialized |= WM_INIT_KEYMAP; } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2f0c1a72be9..413ff181f11 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1735,6 +1735,9 @@ void wm_event_do_handlers(bContext *C) wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win; + /* update key configuration before handling events */ + WM_keyconfig_update(wm); + for(win= wm->windows.first; win; win= win->next) { wmEvent *event; @@ -1938,6 +1941,9 @@ void wm_event_do_handlers(bContext *C) CTX_wm_window_set(C, NULL); } + + /* update key configuration after handling events */ + WM_keyconfig_update(wm); } /* ********** filesector handling ************ */ @@ -2323,27 +2329,32 @@ static void attach_ndof_data(wmEvent* event, const GHOST_TEventNDOFMotionData* g const float s = U.ndof_sensitivity; - data->tvec[0]= s * ghost->tx; - data->rvec[0]= s * ghost->rx; + data->tx = s * ghost->tx; + + data->rx = s * ghost->rx; + data->ry = s * ghost->ry; + data->rz = s * ghost->rz; if (U.ndof_flag & NDOF_ZOOM_UPDOWN) { - // swap Y and Z - data->tvec[1]= s * ghost->tz; - data->tvec[2]= s * ghost->ty; - - // should this affect rotation also? - // initial guess is 'yes', but get user feedback immediately! - data->rvec[1]= s * ghost->rz; - data->rvec[2]= s * ghost->ry; + /* rotate so Y is where Z was */ + data->ty = s * ghost->tz; + data->tz = s * ghost->ty; + /* maintain handed-ness? or just do what feels right? */ + + /* should this affect rotation also? + * initial guess is 'yes', but get user feedback immediately! + */ +#if 0 + /* after turning this on, my guess becomes 'no' */ + data->ry = s * ghost->rz; + data->rz = s * ghost->ry; +#endif } else { - data->tvec[1]= s * ghost->ty; - data->tvec[2]= s * ghost->tz; - - data->rvec[1]= s * ghost->ry; - data->rvec[2]= s * ghost->rz; + data->ty = s * ghost->ty; + data->tz = s * ghost->tz; } data->dt = ghost->dt; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 27fc0caeccc..6b3a574b6b6 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -224,6 +224,14 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) oldwm= oldwmlist->first; wm= G.main->wm.first; + /* move addon key configuration to new wm, to preserve their keymaps */ + if(oldwm->addonconf) { + wm->addonconf= oldwm->addonconf; + BLI_remlink(&oldwm->keyconfigs, oldwm->addonconf); + oldwm->addonconf= NULL; + BLI_addtail(&wm->keyconfigs, wm->addonconf); + } + /* ensure making new keymaps and set space types */ wm->initialized= 0; wm->winactive= NULL; @@ -442,7 +450,7 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) /* called on startup, (context entirely filled with NULLs) */ /* or called for 'New File' */ /* op can be NULL */ -int WM_read_homefile(bContext *C, ReportList *reports, short from_memory) +int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; char tstr[FILE_MAXDIR+FILE_MAXFILE]; @@ -458,7 +466,6 @@ int WM_read_homefile(bContext *C, ReportList *reports, short from_memory) } else { tstr[0] = '\0'; from_memory = 1; - BKE_report(reports, RPT_INFO, "Config directory with "STRINGIFY(BLENDER_STARTUP_FILE)" file not found."); } } @@ -794,11 +801,14 @@ int WM_write_homefile(bContext *C, wmOperator *op) wmWindow *win= CTX_wm_window(C); char filepath[FILE_MAXDIR+FILE_MAXFILE]; int fileflags; - + /* check current window and close it if temp */ if(win->screen->temp) wm_window_close(C, wm, win); + /* update keymaps in user preferences */ + WM_keyconfig_update(wm); + BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); printf("trying to save homefile at %s ", filepath); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index e22829577f4..cf91e219593 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -127,7 +127,8 @@ void WM_init(bContext *C, int argc, const char **argv) } GHOST_CreateSystemPaths(); wm_operatortype_init(); - + WM_menutype_init(); + set_free_windowmanager_cb(wm_close_and_free); /* library.c */ set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ DAG_editors_update_cb(ED_render_id_flush_update); /* depsgraph.c */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 1720c738dd7..6887aa4c717 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -61,14 +61,70 @@ #include "wm_event_system.h" #include "wm_event_types.h" -/* ********************* key config ***********************/ +/******************************* Keymap Item ********************************** + * Item in a keymap, that maps from an event to an operator or modal map item */ -static void keymap_properties_set(wmKeyMapItem *kmi) +static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi) +{ + wmKeyMapItem *kmin = MEM_dupallocN(kmi); + + kmin->prev= kmin->next= NULL; + kmin->flag &= ~KMI_UPDATE; + + if(kmin->properties) { + kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr"); + WM_operator_properties_create(kmin->ptr, kmin->idname); + + kmin->properties= IDP_CopyProperty(kmin->properties); + kmin->ptr->data= kmin->properties; + } + + return kmin; +} + +static void wm_keymap_item_free(wmKeyMapItem *kmi) +{ + /* not kmi itself */ + if(kmi->ptr) { + WM_operator_properties_free(kmi->ptr); + MEM_freeN(kmi->ptr); + } +} + +static void wm_keymap_item_properties_set(wmKeyMapItem *kmi) { WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname); WM_operator_properties_sanitize(kmi->ptr, 1); } +static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b) +{ + if(strcmp(a->idname, b->idname) != 0) + return 0; + + if(!((a->ptr==NULL && b->ptr==NULL) || + (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data)))) + return 0; + + if((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE)) + return 0; + + return (a->propvalue == b->propvalue); +} + +static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b) +{ + return (wm_keymap_item_equals_result(a, b) && + a->type == b->type && + a->val == b->val && + a->shift == b->shift && + a->ctrl == b->ctrl && + a->alt == b->alt && + a->oskey == b->oskey && + a->keymodifier == b->keymodifier && + a->maptype == b->maptype); +} + /* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties) { @@ -78,9 +134,41 @@ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties kmi->ptr = NULL; kmi->properties = properties; - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); +} + +/**************************** Keymap Diff Item ********************************* + * Item in a diff keymap, used for saving diff of keymaps in user preferences */ + +static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi) +{ + wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi); + + kmdin->next = kmdin->prev = NULL; + if(kmdi->add_item) + kmdin->add_item = wm_keymap_item_copy(kmdi->add_item); + if(kmdi->remove_item) + kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item); + + return kmdin; } +static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi) +{ + if(kmdi->remove_item) { + wm_keymap_item_free(kmdi->remove_item); + MEM_freeN(kmdi->remove_item); + } + if(kmdi->add_item) { + wm_keymap_item_free(kmdi->add_item); + MEM_freeN(kmdi->add_item); + } +} + +/***************************** Key Configuration ****************************** + * List of keymaps for all editors, modes, ... . There is a builtin default key + * configuration, a user key configuration, and other preset configurations. */ + wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname) { wmKeyConfig *keyconf; @@ -106,6 +194,7 @@ void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) if (keyconf) { if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) { BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr)); + WM_keyconfig_update_tag(NULL, NULL); } BLI_remlink(&wm->keyconfigs, keyconf); @@ -125,21 +214,6 @@ void WM_keyconfig_free(wmKeyConfig *keyconf) MEM_freeN(keyconf); } -void WM_keyconfig_userdef(void) -{ - wmKeyMap *km; - wmKeyMapItem *kmi; - - for(km=U.keymaps.first; km; km=km->next) { - /* modal keymaps don't have operator properties */ - if ((km->flag & KEYMAP_MODAL) == 0) { - for(kmi=km->items.first; kmi; kmi=kmi->next) { - keymap_properties_set(kmi); - } - } - } -} - static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) { wmKeyConfig *kc; @@ -151,23 +225,84 @@ static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) return NULL; } -/* ************************ free ************************* */ +wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm) +{ + wmKeyConfig *keyconf; -void WM_keymap_free(wmKeyMap *keymap) + /* first try from preset */ + keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); + if(keyconf) + return keyconf; + + /* otherwise use default */ + return wm->defaultconf; +} + +void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname) { - wmKeyMapItem *kmi; + /* setting a different key configuration as active: we ensure all is + updated properly before and after making the change */ + + WM_keyconfig_update(wm); + + BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr)); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); +} + +/********************************** Keymap ************************************* + * List of keymap items for one editor, mode, modal operator, ... */ + +static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid) +{ + wmKeyMap *km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); + + BLI_strncpy(km->idname, idname, KMAP_MAX_NAME); + km->spaceid= spaceid; + km->regionid= regionid; + + return km; +} + +static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap) +{ + wmKeyMap *keymapn = MEM_dupallocN(keymap); + wmKeyMapItem *kmi, *kmin; + wmKeyMapDiffItem *kmdi, *kmdin; + + keymapn->modal_items= keymap->modal_items; + keymapn->poll= keymap->poll; + keymapn->items.first= keymapn->items.last= NULL; + keymapn->flag &= ~(KEYMAP_UPDATE|KEYMAP_EXPANDED); + + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) { + kmdin= wm_keymap_diff_item_copy(kmdi); + BLI_addtail(&keymapn->items, kmdin); + } for(kmi=keymap->items.first; kmi; kmi=kmi->next) { - if(kmi->ptr) { - WM_operator_properties_free(kmi->ptr); - MEM_freeN(kmi->ptr); - } + kmin= wm_keymap_item_copy(kmi); + BLI_addtail(&keymapn->items, kmin); } - BLI_freelistN(&keymap->items); + return keymapn; } -/* ***************** generic call, exported **************** */ +void WM_keymap_free(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; + + for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) + wm_keymap_diff_item_free(kmdi); + + for(kmi=keymap->items.first; kmi; kmi=kmi->next) + wm_keymap_item_free(kmi); + + BLI_freelistN(&keymap->diff_items); + BLI_freelistN(&keymap->items); +} static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier) { @@ -229,7 +364,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty keymap_item_set_id(keymap, kmi); keymap_event_set(kmi, type, val, modifier, keymodifier); - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); } return kmi; } @@ -243,10 +378,12 @@ wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); - keymap_properties_set(kmi); + wm_keymap_item_properties_set(kmi); keymap_item_set_id(keymap, kmi); + WM_keyconfig_update_tag(keymap, kmi); + return kmi; } @@ -266,6 +403,232 @@ void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) MEM_freeN(kmi->ptr); } BLI_freelinkN(&keymap->items, kmi); + + WM_keyconfig_update_tag(keymap, kmi); + } +} + +/************************** Keymap Diff and Patch **************************** + * Rather than saving the entire keymap for user preferences, we only save a + * diff so that changes in the defaults get synced. This system is not perfect + * but works better than overriding the keymap entirely when only few items + * are changed. */ + +static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap) +{ + wmKeyMapItem *kmi, *kmin; + + for(kmi=addonmap->items.first; kmi; kmi=kmi->next) { + kmin = wm_keymap_item_copy(kmi); + keymap_item_set_id(keymap, kmin); + BLI_addhead(&keymap->items, kmin); + } +} + +static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle) +{ + wmKeyMapItem *kmi; + + for(kmi=km->items.first; kmi; kmi=kmi->next) + if(wm_keymap_item_equals(kmi, needle)) + return kmi; + + return NULL; +} + +static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle) +{ + wmKeyMapItem *kmi; + + for(kmi=km->items.first; kmi; kmi=kmi->next) + if(wm_keymap_item_equals_result(kmi, needle)) + return kmi; + + return NULL; +} + +static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km) +{ + wmKeyMapItem *kmi, *to_kmi, *orig_kmi; + wmKeyMapDiffItem *kmdi; + + for(kmi=from_km->items.first; kmi; kmi=kmi->next) { + to_kmi = WM_keymap_item_find_id(to_km, kmi->id); + + if(!to_kmi) { + /* remove item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->remove_item = wm_keymap_item_copy(kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + else if(to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) { + /* replace item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->remove_item = wm_keymap_item_copy(kmi); + kmdi->add_item = wm_keymap_item_copy(to_kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + + /* sync expanded flag back to original so we don't loose it on repatch */ + if(to_kmi) { + orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id); + + if(!orig_kmi) + orig_kmi = wm_keymap_find_item_equals(addon_km, kmi); + + if(orig_kmi) { + orig_kmi->flag &= ~KMI_EXPANDED; + orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED); + } + } + } + + for(kmi=to_km->items.first; kmi; kmi=kmi->next) { + if(kmi->id < 0) { + /* add item */ + kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem"); + kmdi->add_item = wm_keymap_item_copy(kmi); + BLI_addtail(&diff_km->diff_items, kmdi); + } + } +} + +static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) +{ + wmKeyMapDiffItem *kmdi; + wmKeyMapItem *kmi_remove, *kmi_add; + + for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) { + /* find item to remove */ + kmi_remove = NULL; + if(kmdi->remove_item) { + kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item); + if(!kmi_remove) + kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item); + } + + /* add item */ + if(kmdi->add_item) { + /* only if nothing to remove or item to remove found */ + if(!kmdi->remove_item || kmi_remove) { + kmi_add = wm_keymap_item_copy(kmdi->add_item); + kmi_add->flag |= KMI_USER_MODIFIED; + + if(kmi_remove) { + kmi_add->flag &= ~KMI_EXPANDED; + kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED); + kmi_add->id = kmi_remove->id; + BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add); + } + else { + keymap_item_set_id(km, kmi_add); + BLI_addtail(&km->items, kmi_add); + } + } + } + + /* remove item */ + if(kmi_remove) { + wm_keymap_item_free(kmi_remove); + BLI_freelinkN(&km->items, kmi_remove); + } + } +} + +static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap) +{ + wmKeyMap *km; + int expanded = 0; + + /* remove previous keymap in list, we will replace it */ + km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid); + if(km) { + expanded = (km->flag & (KEYMAP_EXPANDED|KEYMAP_CHILDREN_EXPANDED)); + WM_keymap_free(km); + BLI_freelinkN(lb, km); + } + + /* copy new keymap from an existing one */ + if(usermap && !(usermap->flag & KEYMAP_DIFF)) { + /* for compatibiltiy with old user preferences with non-diff + keymaps we override the original entirely */ + wmKeyMapItem *kmi, *orig_kmi; + + km = wm_keymap_copy(usermap); + + /* try to find corresponding id's for items */ + for(kmi=km->items.first; kmi; kmi=kmi->next) { + orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi); + if(!orig_kmi) + orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi); + + if(orig_kmi) + kmi->id = orig_kmi->id; + else + kmi->id = -(km->kmi_id++); + } + + km->flag |= KEYMAP_UPDATE; /* update again to create diff */ + } + else + km = wm_keymap_copy(defaultmap); + + /* add addon keymap items */ + if(addonmap) + wm_keymap_addon_add(km, addonmap); + + /* tag as being user edited */ + if(usermap) + km->flag |= KEYMAP_USER_MODIFIED; + km->flag |= KEYMAP_USER|expanded; + + /* apply user changes of diff keymap */ + if(usermap && (usermap->flag & KEYMAP_DIFF)) + wm_keymap_patch(km, usermap); + + /* add to list */ + BLI_addtail(lb, km); + + return km; +} + +static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km) +{ + wmKeyMap *diffmap, *prevmap, *origmap; + + /* create temporary default + addon keymap for diff */ + origmap = defaultmap; + + if(addonmap) { + defaultmap = wm_keymap_copy(defaultmap); + wm_keymap_addon_add(defaultmap, addonmap); + } + + /* remove previous diff keymap in list, we will replace it */ + prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid); + if(prevmap) { + WM_keymap_free(prevmap); + BLI_freelinkN(lb, prevmap); + } + + /* create diff keymap */ + diffmap= wm_keymap_new(km->idname, km->spaceid, km->regionid); + diffmap->flag |= KEYMAP_DIFF; + wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap); + + /* add to list if not empty */ + if(diffmap->diff_items.first) { + BLI_addtail(lb, diffmap); + } + else { + WM_keymap_free(diffmap); + MEM_freeN(diffmap); + } + + /* free temporary default map */ + if(addonmap) { + WM_keymap_free(defaultmap); + MEM_freeN(defaultmap); } } @@ -292,11 +655,10 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, wmKeyMap *km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); if(km==NULL) { - km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); - BLI_strncpy(km->idname, idname, KMAP_MAX_NAME); - km->spaceid= spaceid; - km->regionid= regionid; + km= wm_keymap_new(idname, spaceid, regionid); BLI_addtail(&keyconf->keymaps, km); + + WM_keyconfig_update_tag(km, NULL); } return km; @@ -304,29 +666,9 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid) { - wmWindowManager *wm = CTX_wm_manager(C); - wmKeyConfig *keyconf; - wmKeyMap *km; - - /* first user defined keymaps */ - km= WM_keymap_list_find(&U.keymaps, idname, spaceid, regionid); - if (km) - return km; - - /* then user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid); - if (km) - return km; - } - - /* then use default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, idname, spaceid, regionid); - if (km) - return km; - else - return NULL; + wmWindowManager *wm= CTX_wm_manager(C); + + return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid); } /* ****************** modal keymaps ************ */ @@ -366,6 +708,8 @@ wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modif keymap_item_set_id(km, kmi); + WM_keyconfig_update_tag(km, kmi); + return kmi; } @@ -588,169 +932,215 @@ int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2) return 1; } -/* ***************** user preferences ******************* */ +/************************* Update Final Configuration ************************* + * On load or other changes, the final user key configuration is rebuilt from + * the preset, addon and user preferences keymaps. We also test if the final + * configuration changed and write the changes to the user preferences. */ -int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap) +static int WM_KEYMAP_UPDATE = 0; + +void WM_keyconfig_update_tag(wmKeyMap *km, wmKeyMapItem *kmi) { - wmKeyConfig *keyconf; - wmKeyMap *km; + /* quick tag to do delayed keymap updates */ + WM_KEYMAP_UPDATE= 1; - if(!keymap) - return 0; + if(km) + km->flag |= KEYMAP_UPDATE; + if(kmi) + kmi->flag |= KMI_UPDATE; +} - /* init from user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - keymap->poll= km->poll; /* lazy init */ - keymap->modal_items= km->modal_items; - return 1; - } - } +static int wm_keymap_test_and_clear_update(wmKeyMap *km) +{ + wmKeyMapItem *kmi; + int update; + + update= (km->flag & KEYMAP_UPDATE); + km->flag &= ~KEYMAP_UPDATE; - /* or from default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - keymap->poll= km->poll; /* lazy init */ - keymap->modal_items= km->modal_items; - return 1; + for(kmi=km->items.first; kmi; kmi=kmi->next) { + update= update || (kmi->flag & KMI_UPDATE); + kmi->flag &= ~KMI_UPDATE; } - - return 0; + + return update; } -wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) +static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km) { - wmKeyConfig *keyconf; - wmKeyMap *km; + wmKeyConfig *keyconf= WM_keyconfig_active(wm); + wmKeyMap *keymap; + keymap= WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid); if(!keymap) - return NULL; - - /* first user defined keymaps */ - km= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - km->poll= keymap->poll; /* lazy init */ - km->modal_items= keymap->modal_items; - return km; - } - - /* then user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - if(km) { - km->poll= keymap->poll; /* lazy init */ - km->modal_items= keymap->modal_items; - return km; - } - } + keymap= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid); - /* then use default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - return km; + return keymap; } -wmKeyMap *WM_keymap_copy_to_user(wmKeyMap *keymap) +void WM_keyconfig_update(wmWindowManager *wm) { - wmKeyMap *usermap; + wmKeyMap *km, *defaultmap, *addonmap, *usermap, *kmn; wmKeyMapItem *kmi; + wmKeyMapDiffItem *kmdi; + int compat_update = 0; - usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - - /* XXX this function is only used by RMB setting hotkeys, and it clears maps on 2nd try this way */ - if(keymap==usermap) - return keymap; + if(!WM_KEYMAP_UPDATE) + return; - if(!usermap) { - /* not saved yet, duplicate existing */ - usermap= MEM_dupallocN(keymap); - usermap->modal_items= NULL; - usermap->poll= NULL; - usermap->flag |= KEYMAP_USER; + /* update operator properties for non-modal user keymaps */ + for(km=U.user_keymaps.first; km; km=km->next) { + if((km->flag & KEYMAP_MODAL) == 0) { + for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) { + if(kmdi->add_item) + wm_keymap_item_properties_set(kmdi->add_item); + if(kmdi->remove_item) + wm_keymap_item_properties_set(kmdi->remove_item); + } - BLI_addtail(&U.keymaps, usermap); + for(kmi=km->items.first; kmi; kmi=kmi->next) + wm_keymap_item_properties_set(kmi); + } } - else { - /* already saved, free items for re-copy */ - WM_keymap_free(usermap); + + /* update U.user_keymaps with user key configuration changes */ + for(km=wm->userconf->keymaps.first; km; km=km->next) { + /* only diff if the user keymap was modified */ + if(wm_keymap_test_and_clear_update(km)) { + /* find keymaps */ + defaultmap= wm_keymap_preset(wm, km); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + + /* diff */ + if(defaultmap) + wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km); + } } - BLI_duplicatelist(&usermap->items, &keymap->items); + /* create user key configuration from preset + addon + user preferences */ + for(km=wm->defaultconf->keymaps.first; km; km=km->next) { + /* find keymaps */ + defaultmap= wm_keymap_preset(wm, km); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + usermap= WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid); - for(kmi=usermap->items.first; kmi; kmi=kmi->next) { - if(kmi->properties) { - kmi->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr"); - WM_operator_properties_create(kmi->ptr, kmi->idname); + /* add */ + kmn= wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); - kmi->properties= IDP_CopyProperty(kmi->properties); - kmi->ptr->data= kmi->properties; + if(kmn) { + kmn->modal_items= km->modal_items; + kmn->poll= km->poll; } + + /* in case of old non-diff keymaps, force extra update to create diffs */ + compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF)); } - for(kmi=keymap->items.first; kmi; kmi=kmi->next) - kmi->flag &= ~KMI_EXPANDED; + WM_KEYMAP_UPDATE= 0; + + if(compat_update) { + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); + } +} + +/********************************* Event Handling ***************************** + * Handlers have pointers to the keymap in the default configuration. During + * event handling this function is called to get the keymap from the final + * configuration. */ + +wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) +{ + wmKeyMap *km; + + if(!keymap) + return NULL; + + /* first user defined keymaps */ + km= WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(km) + return km; - return usermap; + return keymap; } +/******************************* Keymap Editor ******************************** + * In the keymap editor the user key configuration is edited. */ + void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi) { wmWindowManager *wm = CTX_wm_manager(C); - wmKeyConfig *keyconf; - wmKeyMap *km = NULL; + wmKeyMap *defaultmap, *addonmap; + wmKeyMapItem *orig; - /* look in user key config */ - keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); - if(keyconf) { - km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); - } + if(!keymap) + return; - if (!km) { - /* or from default */ - km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + /* construct default keymap from preset + addons */ + defaultmap= wm_keymap_preset(wm, keymap); + addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + + if(addonmap) { + defaultmap = wm_keymap_copy(defaultmap); + wm_keymap_addon_add(defaultmap, addonmap); } - if (km) { - wmKeyMapItem *orig = WM_keymap_item_find_id(km, kmi->id); + /* find original item */ + orig = WM_keymap_item_find_id(defaultmap, kmi->id); - if (orig) { - if(strcmp(orig->idname, kmi->idname) != 0) { - BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname)); + if(orig) { + /* restore to original */ + if(strcmp(orig->idname, kmi->idname) != 0) { + BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname)); + WM_keymap_properties_reset(kmi, NULL); + } - WM_keymap_properties_reset(kmi, NULL); + if (orig->properties) { + if(kmi->properties) { + IDP_FreeProperty(kmi->properties); + MEM_freeN(kmi->properties); + kmi->properties= NULL; } - - if (orig->properties) { - kmi->properties= IDP_CopyProperty(orig->properties); - kmi->ptr->data= kmi->properties; - } - - kmi->propvalue = orig->propvalue; - kmi->type = orig->type; - kmi->val = orig->val; - kmi->shift = orig->shift; - kmi->ctrl = orig->ctrl; - kmi->alt = orig->alt; - kmi->oskey = orig->oskey; - kmi->keymodifier = orig->keymodifier; - kmi->maptype = orig->maptype; + kmi->properties= IDP_CopyProperty(orig->properties); + kmi->ptr->data= kmi->properties; } + kmi->propvalue = orig->propvalue; + kmi->type = orig->type; + kmi->val = orig->val; + kmi->shift = orig->shift; + kmi->ctrl = orig->ctrl; + kmi->alt = orig->alt; + kmi->oskey = orig->oskey; + kmi->keymodifier = orig->keymodifier; + kmi->maptype = orig->maptype; + + WM_keyconfig_update_tag(keymap, kmi); + } + + /* free temporary keymap */ + if(addonmap) { + WM_keymap_free(defaultmap); + MEM_freeN(defaultmap); } } -void WM_keymap_restore_to_default(wmKeyMap *keymap) +void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C) { + wmWindowManager *wm = CTX_wm_manager(C); wmKeyMap *usermap; - usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + /* remove keymap from U.user_keymaps and update */ + usermap= WM_keymap_list_find(&U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid); if(usermap) { WM_keymap_free(usermap); - BLI_freelinkN(&U.keymaps, usermap); + BLI_freelinkN(&U.user_keymaps, usermap); + + WM_keyconfig_update_tag(NULL, NULL); + WM_keyconfig_update(wm); } } @@ -951,3 +1341,4 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) return km; } + diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7238cede2cc..fdf89cfd2be 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -58,6 +58,7 @@ #include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLO_readfile.h" @@ -100,7 +101,7 @@ #include "wm_subwindow.h" #include "wm_window.h" -static ListBase global_ops= {NULL, NULL}; +static GHash *global_ops_hash= NULL; /* ************ operator API, exported ********** */ @@ -113,7 +114,7 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet) WM_operator_bl_idname(idname_bl, idname); if (idname_bl[0]) { - ot= (wmOperatorType *)BLI_findstring_ptr(&global_ops, idname_bl, offsetof(wmOperatorType, idname)); + ot= BLI_ghash_lookup(global_ops_hash, idname_bl); if(ot) { return ot; } @@ -125,9 +126,10 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet) return NULL; } -wmOperatorType *WM_operatortype_first(void) +/* caller must free */ +GHashIterator *WM_operatortype_iter(void) { - return global_ops.first; + return BLI_ghashIterator_new(global_ops_hash); } /* all ops in 1 list (for time being... needs evaluation later) */ @@ -147,7 +149,8 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType*)) RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)"); // XXX All ops should have a description but for now allow them not to. RNA_def_struct_identifier(ot->srna, ot->idname); - BLI_addtail(&global_ops, ot); + + BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType*, void*), void *userdata) @@ -159,7 +162,8 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType*, void*), void *us opfunc(ot, userdata); RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)"); RNA_def_struct_identifier(ot->srna, ot->idname); - BLI_addtail(&global_ops, ot); + + BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } /* ********************* macro operator ******************** */ @@ -351,7 +355,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); // XXX All ops should have a description but for now allow them not to. RNA_def_struct_identifier(ot->srna, ot->idname); - BLI_addtail(&global_ops, ot); + BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); return ot; } @@ -378,7 +382,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), vo RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); RNA_def_struct_identifier(ot->srna, ot->idname); - BLI_addtail(&global_ops, ot); + BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname) @@ -426,14 +430,14 @@ int WM_operatortype_remove(const char *idname) if (ot==NULL) return 0; - BLI_remlink(&global_ops, ot); RNA_struct_free(&BLENDER_RNA, ot->srna); if(ot->macro.first) wm_operatortype_free_macro(ot); - - MEM_freeN(ot); + BLI_ghash_remove(global_ops_hash, (void *)ot->idname, NULL, NULL); + + MEM_freeN(ot); return 1; } @@ -807,6 +811,9 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, if(flag & WM_FILESEL_FILENAME) RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "File Name", "Name of the file"); + if(flag & WM_FILESEL_FILES) + RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); + if (action == FILE_SAVE) { prop= RNA_def_boolean(ot->srna, "check_existing", 1, "Check Existing", "Check and warn on overwriting existing files"); RNA_def_property_flag(prop, PROP_HIDDEN); @@ -1247,7 +1254,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar col = uiLayoutColumn(split, 0); uiItemL(col, "Links", ICON_NONE); uiItemStringO(col, "Donations", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment/"); - uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-258/"); + uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-259/"); uiItemStringO(col, "Manual", ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.5/Manual"); uiItemStringO(col, "Blender Website", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/"); uiItemStringO(col, "User Community", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community/"); // @@ -1311,9 +1318,10 @@ static void operator_call_cb(struct bContext *C, void *UNUSED(arg1), void *arg2) static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items) { - wmOperatorType *ot = WM_operatortype_first(); - - for(; ot; ot= ot->next) { + GHashIterator *iter= WM_operatortype_iter(); + + for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { + wmOperatorType *ot= BLI_ghashIterator_getValue(iter); if((ot->flag & OPTYPE_INTERNAL) && (G.f & G_DEBUG) == 0) continue; @@ -1337,6 +1345,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons } } } + BLI_ghashIterator_free(iter); } static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_op)) @@ -1742,14 +1751,12 @@ static void WM_OT_link_append(wmOperatorType *ot) ot->flag |= OPTYPE_UNDO; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_DIRECTORY|WM_FILESEL_FILENAME| WM_FILESEL_RELPATH); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_DIRECTORY|WM_FILESEL_FILENAME| WM_FILESEL_RELPATH|WM_FILESEL_FILES); RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending"); RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects"); RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer"); RNA_def_boolean(ot->srna, "instance_groups", 1, "Instance Groups", "Create instances for each group as a DupliGroup"); - - RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); } /* *************** recover last session **************** */ @@ -2003,8 +2010,6 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { - int selected = 0; - if(!RNA_property_is_set(op->ptr, "filepath")) { char filepath[FILE_MAX]; BLI_strncpy(filepath, G.main->name, sizeof(filepath)); @@ -2921,7 +2926,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd case PROP_FACTOR: r1= (1 - rc->current_value) * WM_RADIAL_CONTROL_DISPLAY_SIZE; r2= tex_radius= WM_RADIAL_CONTROL_DISPLAY_SIZE; - alpha = rc->current_value / 2 + 0.5; + alpha = rc->current_value / 2.0f + 0.5f; break; case PROP_ANGLE: r1= r2= tex_radius= WM_RADIAL_CONTROL_DISPLAY_SIZE; @@ -3457,26 +3462,31 @@ static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot) RNA_def_boolean(ot->srna, "fast", 0, "Fast NDOF sensitivity change", "If true then sensitivity changes 50%, otherwise 10%"); } + +static void operatortype_ghash_free_cb(wmOperatorType *ot) +{ + if(ot->macro.first) + wm_operatortype_free_macro(ot); + + if(ot->ext.srna) /* python operator, allocs own string */ + MEM_freeN((void *)ot->idname); + + MEM_freeN(ot); +} + /* ******************************************************* */ /* called on initialize WM_exit() */ void wm_operatortype_free(void) { - wmOperatorType *ot; - - for(ot= global_ops.first; ot; ot= ot->next) { - if(ot->macro.first) - wm_operatortype_free_macro(ot); - - if(ot->ext.srna) /* python operator, allocs own string */ - MEM_freeN((void *)ot->idname); - } - - BLI_freelistN(&global_ops); + BLI_ghash_free(global_ops_hash, NULL, (GHashValFreeFP)operatortype_ghash_free_cb); + global_ops_hash= NULL; } /* called on initialize WM_init() */ void wm_operatortype_init(void) { + global_ops_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wm_operatortype_init gh"); + WM_operatortype_append(WM_OT_window_duplicate); WM_operatortype_append(WM_OT_read_homefile); WM_operatortype_append(WM_OT_read_factory_settings); @@ -3719,7 +3729,7 @@ void wm_window_keymap(wmKeyConfig *keyconf) /* menus that can be accessed anywhere in blender */ WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0); - WM_keymap_add_menu(keymap, "VIEW3D_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0); /* Space switching */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */ diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index a87001fb1b4..8ea1f2fdd0a 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -378,7 +378,8 @@ unsigned int index_to_framebuffer(int index) void WM_set_framebuffer_index_color(int index) { - cpack(index_to_framebuffer(index)); + const int col= index_to_framebuffer(index); + cpack(col); } int WM_framebuffer_to_index(unsigned int col) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 87c905c7db6..0ac5157e34f 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -216,10 +216,12 @@ struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spac struct wmKeyConfig *WM_keyconfig_new(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;} struct wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;} void WM_keyconfig_remove(struct wmWindowManager *wm, char *idname){} +void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname) {} void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){} void WM_keymap_restore_to_default(struct wmKeyMap *keymap){} void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){} void WM_keymap_properties_reset(struct wmKeyMapItem *kmi){} +void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi) {} int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap) {return 0;} int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2){return 0;} @@ -391,7 +393,7 @@ void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) {} /* python */ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} -struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;} +struct GHashIterator *WM_operatortype_iter(){return (struct GHashIterator *) NULL;} struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;} struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname){return (struct wmOperatorTypeMacro *) NULL;} int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;} diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 49f00e39110..3f09eee013e 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -254,8 +254,12 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T cam->NodeUpdateGS(0); /* setup rasterizer transformations */ + /* SetViewMatrix may use stereomode which we temporarily disable here */ + RAS_IRasterizer::StereoMode stereomode = ras->GetStereoMode(); + ras->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); ras->SetProjectionMatrix(projectionmat); ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective); + ras->SetStereoMode(stereomode); } void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 8fd0d6e7099..3f802642d33 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -111,7 +111,7 @@ add_test(export_obj_all_objects ${TEST_BLENDER_EXE} --run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_all_objects.obj',use_selection=False,use_nurbs=True\) --md5_source=${TEST_OUT_DIR}/export_obj_all_objects.obj --md5_source=${TEST_OUT_DIR}/export_obj_all_objects.mtl - --md5=01c123948efadc6a71ab2c09a5925756 --md5_method=FILE + --md5=04b3ed97cede07a19548fc518ce9f8ca --md5_method=FILE ) @@ -196,7 +196,7 @@ add_test(export_x3d_cube ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_cube.x3d',use_selection=False\) --md5_source=${TEST_OUT_DIR}/export_x3d_cube.x3d - --md5=5e804c689896116331fa190a9fabbad4 --md5_method=FILE + --md5=2621d8cc2cc1d34f6711c54519907dac --md5_method=FILE ) add_test(export_x3d_nurbs ${TEST_BLENDER_EXE} @@ -204,7 +204,7 @@ add_test(export_x3d_nurbs ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_nurbs.x3d',use_selection=False\) --md5_source=${TEST_OUT_DIR}/export_x3d_nurbs.x3d - --md5=2d5bcf43cf7b6fbbef1c8cc566968fe5 --md5_method=FILE + --md5=d56b3736bab063d101d42079bd276f01 --md5_method=FILE ) add_test(export_x3d_all_objects ${TEST_BLENDER_EXE} @@ -212,7 +212,7 @@ add_test(export_x3d_all_objects ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_all_objects.x3d',use_selection=False\) --md5_source=${TEST_OUT_DIR}/export_x3d_all_objects.x3d - --md5=2809ec13a4cab55d265ce7525c5db1b7 --md5_method=FILE + --md5=0914c9a7fcdbfc5741c1269497e9068b --md5_method=FILE ) @@ -273,7 +273,7 @@ add_test(export_fbx_cube ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_cube.fbx',use_selection=False,use_metadata=False\) --md5_source=${TEST_OUT_DIR}/export_fbx_cube.fbx - --md5=83dca99a0cb338852b8c85951a44c68a --md5_method=FILE + --md5=86da2495dffd7c270e682f599be6b3d1 --md5_method=FILE ) add_test(export_fbx_nurbs ${TEST_BLENDER_EXE} @@ -281,7 +281,7 @@ add_test(export_fbx_nurbs ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_nurbs.fbx',use_selection=False,use_metadata=False\) --md5_source=${TEST_OUT_DIR}/export_fbx_nurbs.fbx - --md5=c7d9491ffa6264e820ed1e12df63f871 --md5_method=FILE + --md5=88a263ddb5181e6522dc214debb92ced --md5_method=FILE ) add_test(export_fbx_all_objects ${TEST_BLENDER_EXE} @@ -289,5 +289,5 @@ add_test(export_fbx_all_objects ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_all_objects.fbx',use_selection=False,use_metadata=False\) --md5_source=${TEST_OUT_DIR}/export_fbx_all_objects.fbx - --md5=22867f82e1615fd1eae18cfaac8ba035 --md5_method=FILE + --md5=e6f75fe7de9aa366896456e13eafc76a --md5_method=FILE ) diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py index 668b4e69228..b64055df252 100644 --- a/source/tests/bl_run_operators.py +++ b/source/tests/bl_run_operators.py @@ -70,7 +70,7 @@ def run_ops(operators, setup_func=None): setup_func() - for mode in ('EXEC_DEFAULT', 'INVOKE_DEFAULT'): + for mode in {'EXEC_DEFAULT', 'INVOKE_DEFAULT'}: try: op(mode) except: |