2.5
***** first commit in a long time, and its great to be back! commited Select Mirror operator for objects eg. L.sword->R.sword added to 3dview select menu aswel the hotkey is shift-ctrl-m (hope its not taken)
This commit is contained in:
@@ -167,6 +167,7 @@ class VIEW3D_MT_select_OBJECT(bpy.types.Menu):
|
|||||||
layout.itemO("object.select_all_toggle", text="Select/Deselect All")
|
layout.itemO("object.select_all_toggle", text="Select/Deselect All")
|
||||||
layout.itemO("object.select_inverse", text="Inverse")
|
layout.itemO("object.select_inverse", text="Inverse")
|
||||||
layout.itemO("object.select_random", text="Random")
|
layout.itemO("object.select_random", text="Random")
|
||||||
|
layout.itemO("object.select_mirror", text="Mirror")
|
||||||
layout.itemO("object.select_by_layer", text="Select All by Layer")
|
layout.itemO("object.select_by_layer", text="Select All by Layer")
|
||||||
layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...")
|
layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...")
|
||||||
layout.itemO("object.select_grouped", text="Select Grouped...")
|
layout.itemO("object.select_grouped", text="Select Grouped...")
|
||||||
|
@@ -28,6 +28,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@@ -2189,6 +2191,165 @@ void OBJECT_OT_select_all_toggle(wmOperatorType *ot)
|
|||||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/* ****** select mirror *******/
|
||||||
|
/* finds the best possible flipped name. For renaming; check for unique names afterwards */
|
||||||
|
/* if strip_number: removes number extensions */
|
||||||
|
void object_flip_name (char *name)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char prefix[128]={""}; /* The part before the facing */
|
||||||
|
char suffix[128]={""}; /* The part after the facing */
|
||||||
|
char replace[128]={""}; /* The replacement string */
|
||||||
|
char number[128]={""}; /* The number extension string */
|
||||||
|
char *index=NULL;
|
||||||
|
|
||||||
|
len= strlen(name);
|
||||||
|
if(len<3) return; // we don't do names like .R or .L
|
||||||
|
|
||||||
|
/* We first check the case with a .### extension, let's find the last period */
|
||||||
|
if(isdigit(name[len-1])) {
|
||||||
|
index= strrchr(name, '.'); // last occurrance
|
||||||
|
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
|
||||||
|
strcpy(number, index);
|
||||||
|
*index= 0;
|
||||||
|
len= strlen(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (prefix, name);
|
||||||
|
|
||||||
|
#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
|
||||||
|
|
||||||
|
/* first case; separator . - _ with extensions r R l L */
|
||||||
|
if( IS_SEPARATOR(name[len-2]) ) {
|
||||||
|
switch(name[len-1]) {
|
||||||
|
case 'l':
|
||||||
|
prefix[len-1]= 0;
|
||||||
|
strcpy(replace, "r");
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
prefix[len-1]= 0;
|
||||||
|
strcpy(replace, "l");
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
prefix[len-1]= 0;
|
||||||
|
strcpy(replace, "R");
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
prefix[len-1]= 0;
|
||||||
|
strcpy(replace, "L");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* case; beginning with r R l L , with separator after it */
|
||||||
|
else if( IS_SEPARATOR(name[1]) ) {
|
||||||
|
switch(name[0]) {
|
||||||
|
case 'l':
|
||||||
|
strcpy(replace, "r");
|
||||||
|
strcpy(suffix, name+1);
|
||||||
|
prefix[0]= 0;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
strcpy(replace, "l");
|
||||||
|
strcpy(suffix, name+1);
|
||||||
|
prefix[0]= 0;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
strcpy(replace, "R");
|
||||||
|
strcpy(suffix, name+1);
|
||||||
|
prefix[0]= 0;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
strcpy(replace, "L");
|
||||||
|
strcpy(suffix, name+1);
|
||||||
|
prefix[0]= 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(len > 5) {
|
||||||
|
/* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
|
||||||
|
index = BLI_strcasestr(prefix, "right");
|
||||||
|
if (index==prefix || index==prefix+len-5) {
|
||||||
|
if(index[0]=='r')
|
||||||
|
strcpy (replace, "left");
|
||||||
|
else {
|
||||||
|
if(index[1]=='I')
|
||||||
|
strcpy (replace, "LEFT");
|
||||||
|
else
|
||||||
|
strcpy (replace, "Left");
|
||||||
|
}
|
||||||
|
*index= 0;
|
||||||
|
strcpy (suffix, index+5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
index = BLI_strcasestr(prefix, "left");
|
||||||
|
if (index==prefix || index==prefix+len-4) {
|
||||||
|
if(index[0]=='l')
|
||||||
|
strcpy (replace, "right");
|
||||||
|
else {
|
||||||
|
if(index[1]=='E')
|
||||||
|
strcpy (replace, "RIGHT");
|
||||||
|
else
|
||||||
|
strcpy (replace, "Right");
|
||||||
|
}
|
||||||
|
*index= 0;
|
||||||
|
strcpy (suffix, index+4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef IS_SEPARATOR
|
||||||
|
|
||||||
|
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int object_select_mirror_exec(bContext *C, wmOperator *op)
|
||||||
|
{
|
||||||
|
char tmpname[32];
|
||||||
|
short seltype;
|
||||||
|
|
||||||
|
seltype = RNA_enum_get(op->ptr, "seltype");
|
||||||
|
|
||||||
|
CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) {
|
||||||
|
|
||||||
|
strcpy(tmpname, primbase->object->id.name+2);
|
||||||
|
object_flip_name(tmpname);
|
||||||
|
|
||||||
|
CTX_DATA_BEGIN(C, Base*, secbase, visible_bases) {
|
||||||
|
if(!strcmp(secbase->object->id.name+2, tmpname)) {
|
||||||
|
ED_base_object_select(secbase, BA_SELECT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CTX_DATA_END;
|
||||||
|
|
||||||
|
if (seltype == 0) ED_base_object_select(primbase, BA_DESELECT);
|
||||||
|
|
||||||
|
}
|
||||||
|
CTX_DATA_END;
|
||||||
|
|
||||||
|
/* undo? */
|
||||||
|
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
|
||||||
|
|
||||||
|
return OPERATOR_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OBJECT_OT_select_mirror(wmOperatorType *ot)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* identifiers */
|
||||||
|
ot->name= "Select Mirror";
|
||||||
|
ot->description = "Select the Mirror objects of the selected object eg. L.sword -> R.sword";
|
||||||
|
ot->idname= "OBJECT_OT_select_mirror";
|
||||||
|
|
||||||
|
/* api callbacks */
|
||||||
|
ot->exec= object_select_mirror_exec;
|
||||||
|
ot->poll= ED_operator_scene_editable;
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||||
|
|
||||||
|
RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
|
||||||
|
}
|
||||||
/* ****** random selection *******/
|
/* ****** random selection *******/
|
||||||
|
|
||||||
static int object_select_random_exec(bContext *C, wmOperator *op)
|
static int object_select_random_exec(bContext *C, wmOperator *op)
|
||||||
|
@@ -54,6 +54,7 @@ void OBJECT_OT_select_by_type(struct wmOperatorType *ot);
|
|||||||
void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
|
void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_select_linked(struct wmOperatorType *ot);
|
void OBJECT_OT_select_linked(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_select_grouped(struct wmOperatorType *ot);
|
void OBJECT_OT_select_grouped(struct wmOperatorType *ot);
|
||||||
|
void OBJECT_OT_select_mirror(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_location_clear(struct wmOperatorType *ot);
|
void OBJECT_OT_location_clear(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_rotation_clear(struct wmOperatorType *ot);
|
void OBJECT_OT_rotation_clear(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_scale_clear(struct wmOperatorType *ot);
|
void OBJECT_OT_scale_clear(struct wmOperatorType *ot);
|
||||||
|
@@ -79,6 +79,7 @@ void ED_operatortypes_object(void)
|
|||||||
WM_operatortype_append(OBJECT_OT_select_by_layer);
|
WM_operatortype_append(OBJECT_OT_select_by_layer);
|
||||||
WM_operatortype_append(OBJECT_OT_select_linked);
|
WM_operatortype_append(OBJECT_OT_select_linked);
|
||||||
WM_operatortype_append(OBJECT_OT_select_grouped);
|
WM_operatortype_append(OBJECT_OT_select_grouped);
|
||||||
|
WM_operatortype_append(OBJECT_OT_select_mirror);
|
||||||
WM_operatortype_append(OBJECT_OT_location_clear);
|
WM_operatortype_append(OBJECT_OT_location_clear);
|
||||||
WM_operatortype_append(OBJECT_OT_rotation_clear);
|
WM_operatortype_append(OBJECT_OT_rotation_clear);
|
||||||
WM_operatortype_append(OBJECT_OT_scale_clear);
|
WM_operatortype_append(OBJECT_OT_scale_clear);
|
||||||
@@ -192,6 +193,7 @@ void ED_keymap_object(wmWindowManager *wm)
|
|||||||
WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
|
WM_keymap_add_item(keymap, "OBJECT_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
|
||||||
WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
|
WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
|
||||||
WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
|
WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
|
||||||
|
WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
|
||||||
|
|
||||||
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
|
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
|
||||||
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
|
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
|
||||||
|
Reference in New Issue
Block a user