forked from bartvdbraak/blender
Added select grouped property (objects with shared property names will be selected)
(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.
This commit is contained in:
parent
e11cd5a962
commit
a9988317c9
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -136,7 +136,7 @@
|
||||
#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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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(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);
|
||||
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
for(base= FIRSTBASE; base; base= base->next) {
|
||||
if((base != BASACT) && TESTBASELIB(base)) {
|
||||
set_ob_property(base->object, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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[]= {
|
||||
|
Loading…
Reference in New Issue
Block a user