Added select grouped property (objects with shared property names will be selected)
authorCampbell Barton <ideasman42@gmail.com>
Sun, 21 Sep 2008 10:12:33 +0000 (10:12 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 21 Sep 2008 10:12:33 +0000 (10:12 +0000)
(updated select group toolbox and header menu)

Added 2 copy property options - Replace All and Merge All, since there was no way to remove all properties, or set all objects game properties to be the same as the active objects.
Added set_ob_property(ob, prop) to property api.

bugfix in python api, copyAllPropertiesTo, it didnt check for duplicates or that it wasnt copying from/to the same object.

source/blender/blenkernel/BKE_property.h
source/blender/blenkernel/intern/property.c
source/blender/blenloader/intern/readfile.c
source/blender/python/api2_2x/Object.c
source/blender/src/drawmesh.c
source/blender/src/drawobject.c
source/blender/src/editobject.c
source/blender/src/header_view3d.c
source/blender/src/space.c
source/blender/src/toolbox.c

index f1587790c4ad9741a88e4586da5fd8c5445f4e21..6af1deda72705d49359b719b76eab0912b24348c 100644 (file)
@@ -41,7 +41,8 @@ struct bProperty *copy_property(struct bProperty *prop);
 void copy_properties(struct ListBase *lbn, struct ListBase *lbo);
 void init_property(struct bProperty *prop);
 struct bProperty *new_property(int type);
-struct bProperty *get_property(struct Object *ob, char *name);
+struct bProperty *get_ob_property(struct Object *ob, char *name);
+void set_ob_property(struct Object *ob, struct bProperty *propc);
 int compare_property(struct bProperty *prop, char *str);
 void set_property(struct bProperty *prop, char *str);
 void add_property(struct bProperty *prop, char *str);
index f55bdd152792ade7dd052ee7fdcf74185eabffdb..d2eb058a9a0512a69a23778ba8f1a641e42e79c5 100644 (file)
@@ -83,8 +83,7 @@ bProperty *copy_property(bProperty *prop)
 void copy_properties(ListBase *lbn, ListBase *lbo)
 {
        bProperty *prop, *propn;
-       
-       lbn->first= lbn->last= 0;
+       free_properties( lbn ); /* incase we are copying to an object with props */
        prop= lbo->first;
        while(prop) {
                propn= copy_property(prop);
@@ -139,7 +138,7 @@ bProperty *new_property(int type)
        return prop;
 }
 
-bProperty *get_property(Object *ob, char *name)
+bProperty *get_ob_property(Object *ob, char *name)
 {
        bProperty *prop;
        
@@ -151,6 +150,17 @@ bProperty *get_property(Object *ob, char *name)
        return NULL;
 }
 
+void set_ob_property(Object *ob, bProperty *propc)
+{
+       bProperty *prop;
+       prop= get_ob_property(ob, propc->name);
+       if(prop) {
+               free_property(prop);
+               BLI_remlink(&ob->prop, prop);
+       }
+       BLI_addtail(&ob->prop, copy_property(propc));
+}
+
 /* negative: prop is smaller
  * positive: prop is larger
  */
index 80defdbbf9c6de11b5c927f276425772012e1a01..b013b51c026398924a6fc1b2b1aaf552b00e8081 100644 (file)
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
-#include "BKE_property.h" // for get_property
+#include "BKE_property.h" // for get_ob_property
 #include "BKE_sca.h" // for init_actuator
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
@@ -5325,7 +5325,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        while (act) {
                                if(act->type==ACT_IPO) {
                                        ia= act->data;
-                                       prop= get_property(ob, ia->name);
+                                       prop= get_ob_property(ob, ia->name);
                                        if(prop) {
                                                ia->type= ACT_IPO_FROM_PROP;
                                        }
index 5151fae8c65a2c57ddec013d4ba5214c96ebad4f..1e5445cbd80d476200a430cacd5d45c7b10fa91e 100644 (file)
@@ -3002,7 +3002,7 @@ static PyObject *Object_getProperty( BPy_Object * self, PyObject * args )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                "expected a string" );
 
-       prop = get_property( self->object, prop_name );
+       prop = get_ob_property( self->object, prop_name );
        if( prop )
                return Property_CreatePyObject( prop );
 
@@ -3018,7 +3018,7 @@ static PyObject *Object_addProperty( BPy_Object * self, PyObject * args )
        char *prop_type = NULL;
        short type = -1;
        BPy_Property *py_prop = NULL;
-       int argslen = PyObject_Length( args );
+       int argslen = PyTuple_Size( args );
 
        if( argslen == 3 || argslen == 2 ) {
                if( !PyArg_ParseTuple( args, "sO|s", &prop_name, &prop_data,
@@ -3129,7 +3129,7 @@ static PyObject *Object_removeProperty( BPy_Object * self, PyObject * args )
                        py_prop->property = NULL;
                }
        } else {
-               prop = get_property( self->object, prop_name );
+               prop = get_ob_property( self->object, prop_name );
                if( prop ) {
                        BLI_remlink( &self->object->prop, prop );
                        free_property( prop );
@@ -3148,18 +3148,23 @@ static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
                                             PyObject * args )
 {
        PyObject *dest;
+       Object *dest_ob;
        bProperty *prop = NULL;
        bProperty *propn = NULL;
 
        if( !PyArg_ParseTuple( args, "O!", &Object_Type, &dest ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
                                "expected an Object" );
-
+       
+       if (dest == (PyObject *)self) {
+               Py_RETURN_NONE;
+       }
+       dest_ob = ( ( BPy_Object * ) dest )->object;
+       
        /*make a copy of all its properties*/
        prop = self->object->prop.first;
        while( prop ) {
-               propn = copy_property( prop );
-               BLI_addtail( &( ( BPy_Object * ) dest )->object->prop, propn );
+               set_ob_property( dest_ob, prop );
                prop = prop->next;
        }
 
index 8f22c704fd023198782ec8d768e20d767d621b5b..ba266fa8c297bd264e35f483537701ee22d6ee24 100644 (file)
@@ -467,7 +467,7 @@ void draw_mesh_text(Object *ob, int glsl)
        MFace *mf, *mface= me->mface;
        MTFace *tface= me->mtface;
        MCol *mcol= me->mcol;   /* why does mcol exist? */
-       bProperty *prop = get_property(ob, "Text");
+       bProperty *prop = get_ob_property(ob, "Text");
        GPUVertexAttribs gattribs;
        int a, totface= me->totface;
 
@@ -568,7 +568,7 @@ void draw_mesh_textured(Object *ob, DerivedMesh *dm, int faceselect)
                dm->drawFacesTex(dm, draw_tface__set_draw);
 
        /* draw game engine text hack */
-       if(get_property(ob, "Text")) 
+       if(get_ob_property(ob, "Text")) 
                draw_mesh_text(ob, 0);
 
        draw_textured_end();
index f5a4ac4556ac30bb87197a3a9f3d78aa95196b4c..527b36d0df418813358a65ed0e27723a6112b5ae 100644 (file)
@@ -2281,7 +2281,7 @@ static void draw_mesh_fancy(Base *base, int dt, int flag)
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                        dm->drawFacesGLSL(dm, GPU_enable_material);
-                       if(get_property(ob, "Text"))
+                       if(get_ob_property(ob, "Text"))
                                draw_mesh_text(ob, 1);
                        GPU_disable_material();
 
index ef909a1e810bd11b0175869adf8fac1376d405e7..29d7b52487f3a594f1591aa8fda7cd00aa36eb87 100644 (file)
@@ -3192,7 +3192,7 @@ void flip_subdivison(int level)
  
 static void copymenu_properties(Object *ob)
 {      
-       bProperty *prop, *propn, *propc;
+       bProperty *prop;
        Base *base;
        int nr, tot=0;
        char *str;
@@ -3208,45 +3208,43 @@ static void copymenu_properties(Object *ob)
                return;
        }
        
-       str= MEM_callocN(24+32*tot, "copymenu prop");
+       str= MEM_callocN(50 + 33*tot, "copymenu prop");
        
-       strcpy(str, "Copy Property %t");
+       strcpy(str, "Copy Property %t|Replace All|Merge All|%l");
        
        tot= 0; 
        prop= ob->prop.first;
        while(prop) {
                tot++;
-               strcat(str, " |");
+               strcat(str, "|");
                strcat(str, prop->name);
                prop= prop->next;
        }
 
        nr= pupmenu(str);
-       if(nr>0) {
-               tot= 0;
-               prop= ob->prop.first;
-               while(prop) {
-                       tot++;
-                       if(tot==nr) break;
-                       prop= prop->next;
+       
+       if ( nr==1 || nr==2 ) {
+               base= FIRSTBASE;
+               while(base) {
+                       if((base != BASACT) && TESTBASELIB(base)) {
+                               if (nr==1) { /* replace */
+                                       copy_properties( &base->object->prop, &ob->prop );
+                               } else {
+                                       for(prop = ob->prop.first; prop; prop= prop->next ) {
+                                               set_ob_property(base->object, prop);
+                                       }
+                               }
+                       }
+                       base= base->next;
                }
+       } else if(nr>0) {
+               prop = BLI_findlink(&ob->prop, nr-4); /* account for first 3 menu items & menu index starting at 1*/
+               
                if(prop) {
-                       propc= prop;
-                       
-                       base= FIRSTBASE;
-                       while(base) {
-                               if(base != BASACT) {
-                                       if(TESTBASELIB(base)) {
-                                               prop= get_property(base->object, propc->name);
-                                               if(prop) {
-                                                       free_property(prop);
-                                                       BLI_remlink(&base->object->prop, prop);
-                                               }
-                                               propn= copy_property(propc);
-                                               BLI_addtail(&base->object->prop, propn);
-                                       }
+                       for(base= FIRSTBASE; base; base= base->next) {
+                               if((base != BASACT) && TESTBASELIB(base)) {
+                                       set_ob_property(base->object, prop);
                                }
-                               base= base->next;
                        }
                }
        }
index 36ba819b3f126324a44420d069b64031bcdfd76e..827103cbb32d9c717a0291f3b6c9d0d70640d2f2 100644 (file)
@@ -885,6 +885,8 @@ void do_view3d_select_object_groupedmenu(void *arg, int event)
        case 7: /* Objects in Same Group */
        case 8: /* Object Hooks*/
        case 9: /* Object PassIndex*/
+       case 10: /* Object Color*/
+       case 11: /* Game Properties*/
                select_object_grouped((short)event);
                break;
        }
@@ -907,7 +909,9 @@ static uiBlock *view3d_select_object_groupedmenu(void *arg_unused)
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Objects on Shared Layers|Shift G, 6",            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Objects in Same Group|Shift G, 7",               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Hooks|Shift G, 8",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object PassIndex|Shift G, 9",            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");   
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object PassIndex|Shift G, 9",            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Color|Shift G, 0",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");  
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Game Properties|Shift G, Alt+1",         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");  
 
        uiBlockSetDirection(block, UI_RIGHT);
        uiTextBoundsBlock(block, 60);
index 198d8140aceb3c96ab7d8d8b7f37ddcc239bd474..d4460e55a3eb2773d5567a28c6cda07977325f5f 100644 (file)
@@ -64,6 +64,7 @@
 #include "DNA_modifier_types.h" /* used for select grouped hooks */
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
+#include "DNA_property_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_sequence_types.h"
@@ -93,7 +94,6 @@
 #include "BKE_utildefines.h"
 #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
 #include "BKE_particle.h"
-
 #include "BIF_spacetypes.h"  /* first, nasty dependency with typedef */
 
 #include "BIF_butspace.h"
@@ -710,7 +710,7 @@ static short select_parent(void)    /* Makes parent active and de-selected OBACT */
        short changed = 0;
        Base *base, *startbase, *basact=NULL, *oldbasact;
        
-       if (!(OBACT) || !(OBACT->parent)) return 0;
+       if (!(OBACT->parent)) return 0; /* we know OBACT is valid */
        BASACT->flag &= (~SELECT);
        BASACT->object->flag &= (~SELECT);
        startbase=  FIRSTBASE;
@@ -746,9 +746,6 @@ static short select_same_group(Object *ob)  /* Select objects in the same group a
        char str[10 + (24*GROUP_MENU_MAX)];
        char *p = str;
        int group_count=0, menu, i;
-
-       if (!ob)
-               return 0;
        
        for (   group=G.main->group.first;
                        group && group_count < GROUP_MENU_MAX;
@@ -804,9 +801,6 @@ static short select_object_hooks(Object *ob)
        ModifierData *md;
        HookModifierData *hmd;
        
-       if (!ob)
-               return 0;
-       
        for (md = ob->modifiers.first; md; md=md->next) {
                if (md->type==eModifierType_Hook) {
                        hmd= (HookModifierData*) md;
@@ -829,8 +823,6 @@ static short select_same_parent(Object *ob)
 {
        short changed = 0;
        Base *base;
-       if (!ob)
-               return 0;
        
        for (base= FIRSTBASE; base; base= base->next) {
                if (BASE_SELECTABLE(base) && (base->object->parent==ob->parent)  && !(base->flag & SELECT)) {
@@ -846,8 +838,6 @@ static short select_same_type(Object *ob)
 {
        short changed = 0;
        Base *base;
-       if (!ob)
-               return 0;
        
        for (base= FIRSTBASE; base; base= base->next) {
                if (BASE_SELECTABLE(base) && (base->object->type == ob->type) && !(base->flag & SELECT)) {
@@ -864,9 +854,6 @@ static short select_same_layer(Object *ob)
        char changed = 0;
        Base *base = FIRSTBASE;
        
-       if (!ob)
-               return 0;
-       
        while(base) {
                if (BASE_SELECTABLE(base) && (base->lay & ob->lay) && !(base->flag & SELECT)) {
                        base->flag |= SELECT;
@@ -883,9 +870,6 @@ static short select_same_index_object(Object *ob)
        char changed = 0;
        Base *base = FIRSTBASE;
        
-       if (!ob)
-               return 0;
-       
        while(base) {
                if (BASE_SELECTABLE(base) && (base->object->index == ob->index) && !(base->flag & SELECT)) {
                        base->flag |= SELECT;
@@ -902,9 +886,6 @@ static short select_same_color(Object *ob)
        char changed = 0;
        Base *base = FIRSTBASE;
        
-       if (!ob)
-               return 0;
-       
        while(base) {
                if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005))) {
                        base->flag |= SELECT;
@@ -916,19 +897,52 @@ static short select_same_color(Object *ob)
        return changed;
 }
 
+static short objects_share_gameprop(Object *a, Object *b)
+{
+       bProperty *prop;
+       /*make a copy of all its properties*/
+       
+       for( prop= a->prop.first; prop; prop = prop->next ) {
+               if ( get_ob_property(b, prop->name) )
+                       return 1;
+       }
+       return 0;
+}
+
+static short select_same_gameprops(Object *ob)
+{
+       char changed = 0;
+       Base *base = FIRSTBASE;
+       
+       while(base) {
+               if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
+                       base->flag |= SELECT;
+                       base->object->flag |= SELECT;
+                       changed = 1;
+               }
+               base= base->next;
+       }
+       return changed;
+}
+
 void select_object_grouped(short nr)
 {
+       Object *ob = OBACT;
        short changed = 0;
-       if(nr==1)               changed = select_children(OBACT, 1);
-       else if(nr==2)  changed = select_children(OBACT, 0);
+       
+       if (ob==NULL) return;
+       
+       if(nr==1)               changed = select_children(ob, 1);
+       else if(nr==2)  changed = select_children(ob, 0);
        else if(nr==3)  changed = select_parent();
-       else if(nr==4)  changed = select_same_parent(OBACT);    
-       else if(nr==5)  changed = select_same_type(OBACT);
-       else if(nr==6)  changed = select_same_layer(OBACT);     
-       else if(nr==7)  changed = select_same_group(OBACT);
-       else if(nr==8)  changed = select_object_hooks(OBACT);
-       else if(nr==9)  changed = select_same_index_object(OBACT);
-       else if(nr==10) changed = select_same_color(OBACT);
+       else if(nr==4)  changed = select_same_parent(ob);       
+       else if(nr==5)  changed = select_same_type(ob);
+       else if(nr==6)  changed = select_same_layer(ob);        
+       else if(nr==7)  changed = select_same_group(ob);
+       else if(nr==8)  changed = select_object_hooks(ob);
+       else if(nr==9)  changed = select_same_index_object(ob);
+       else if(nr==10) changed = select_same_color(ob);
+       else if(nr==11) changed = select_same_gameprops(ob);
        
        if (changed) {
                countall();
@@ -956,7 +970,8 @@ static void select_object_grouped_menu(void)
                 "Objects in Same Group%x7|"
                 "Object Hooks%x8|"
                                "Object PassIndex%x9|"
-                               "Object Color%x10");
+                               "Object Color%x10|"
+                               "Game Properties%x11");
 
        /* here we go */
        
index f38affde4182ade4928e5ab61a6f1d50fbeab311..55feb4c030557f7368674d97a201dd2bd3d86199 100644 (file)
@@ -897,6 +897,8 @@ static TBitem tb_object_select_grouped[]= {
 {      0, "Objects in Same Group|Shift G, 7",  7, NULL},
 {      0, "Object Hooks|Shift G, 8",   8, NULL},
 {      0, "Object PassIndex|Shift G, 9",       9, NULL},
+{      0, "Object Color|Shift G, 0",   9, NULL},
+{      0, "Game Properties|Shift G, Alt+1",    9, NULL},
 {  -1, "",                     0, do_view3d_select_object_groupedmenu}};
 
 static TBitem tb_object_select[]= {