forked from bartvdbraak/blender
[Coder API's]: Added a "generic unique name-finding function".
Basically, this is based on the behaviour of the unique_constraint_name (or equivilant) functions, which have traditionally been duplicated everytime a new datatype needed this. Currently, this is in use for the following things: * Constraints * Action/Bone Groups * Local Action Markers / PoseLib poses Usage Notes: * The file in which this is to be used should include the standard header file <stddef.h>. This defines the offsetof() macro, which should be used to find the relative location of the "name" member of the structs * This function is only designed for names of up to 128 chars in length (Most names are at most 32. TimeMarkers are 64). If a longer string needs to be handled, the function will need to be modified accordingly. * defname is the default name that should be used in case one hasn't been specified already
This commit is contained in:
parent
6f4c03a091
commit
aa03132bc3
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -226,55 +227,7 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime,
|
|||||||
/* Find the first available, non-duplicate name for a given constraint */
|
/* Find the first available, non-duplicate name for a given constraint */
|
||||||
void unique_constraint_name (bConstraint *con, ListBase *list)
|
void unique_constraint_name (bConstraint *con, ListBase *list)
|
||||||
{
|
{
|
||||||
bConstraint *curcon;
|
BLI_uniquename(list, con, "Const", offsetof(bConstraint, name), 32);
|
||||||
char tempname[64];
|
|
||||||
int number = 1, exists = 0;
|
|
||||||
char *dot;
|
|
||||||
|
|
||||||
/* See if we are given an empty string */
|
|
||||||
if (con->name[0] == '\0') {
|
|
||||||
/* give it default name first */
|
|
||||||
strcpy(con->name, "Const");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if we even need to do this */
|
|
||||||
if (list == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (curcon = list->first; curcon; curcon=curcon->next) {
|
|
||||||
if (curcon != con) {
|
|
||||||
if (!strcmp(curcon->name, con->name)) {
|
|
||||||
exists = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exists == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Strip off the suffix */
|
|
||||||
dot = strchr(con->name, '.');
|
|
||||||
if (dot)
|
|
||||||
*dot=0;
|
|
||||||
|
|
||||||
for (number = 1; number <= 999; number++) {
|
|
||||||
sprintf(tempname, "%s.%03d", con->name, number);
|
|
||||||
|
|
||||||
exists = 0;
|
|
||||||
for (curcon=list->first; curcon; curcon=curcon->next) {
|
|
||||||
if (con != curcon) {
|
|
||||||
if (strcmp(curcon->name, tempname)==0) {
|
|
||||||
exists = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exists == 0) {
|
|
||||||
strcpy(con->name, tempname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------- Evaluation Loop Preparation --------------- */
|
/* ----------------- Evaluation Loop Preparation --------------- */
|
||||||
|
@ -107,6 +107,7 @@ int BLI_findindex(struct ListBase *listbase, void *vlink);
|
|||||||
void BLI_freelistN(struct ListBase *listbase);
|
void BLI_freelistN(struct ListBase *listbase);
|
||||||
void BLI_addtail(struct ListBase *listbase, void *vlink);
|
void BLI_addtail(struct ListBase *listbase, void *vlink);
|
||||||
void BLI_remlink(struct ListBase *listbase, void *vlink);
|
void BLI_remlink(struct ListBase *listbase, void *vlink);
|
||||||
|
void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], short name_offs, short len);
|
||||||
void BLI_newname(char * name, int add);
|
void BLI_newname(char * name, int add);
|
||||||
int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen);
|
int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen);
|
||||||
void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic);
|
void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic);
|
||||||
|
@ -220,6 +220,79 @@ void BLI_newname(char *name, int add)
|
|||||||
BLI_stringenc(name, head, tail, digits, pic);
|
BLI_stringenc(name, head, tail, digits, pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* little helper macro for BLI_uniquename */
|
||||||
|
#ifndef GIVE_STRADDR
|
||||||
|
#define GIVE_STRADDR(data, offset) ( ((char *)data) + offset )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generic function to set a unique name. It is only designed to be used in situations
|
||||||
|
* where the name is part of the struct, and also that the name is at most 128 chars long.
|
||||||
|
*
|
||||||
|
* For places where this is used, see constraint.c for example...
|
||||||
|
*
|
||||||
|
* name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h
|
||||||
|
* len: maximum length of string (to prevent overflows, etc.)
|
||||||
|
* defname: the name that should be used by default if none is specified already
|
||||||
|
*/
|
||||||
|
void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs, short len)
|
||||||
|
{
|
||||||
|
Link *link;
|
||||||
|
char tempname[128];
|
||||||
|
int number = 1, exists = 0;
|
||||||
|
char *dot;
|
||||||
|
|
||||||
|
/* Make sure length can be handled */
|
||||||
|
if ((len < 0) || (len > 128))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* See if we are given an empty string */
|
||||||
|
if (ELEM(NULL, vlink, defname))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GIVE_STRADDR(vlink, name_offs) == '\0') {
|
||||||
|
/* give it default name first */
|
||||||
|
BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if we even need to do this */
|
||||||
|
if (list == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (link = list->first; link; link= link->next) {
|
||||||
|
if (link != vlink) {
|
||||||
|
if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) {
|
||||||
|
exists = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Strip off the suffix */
|
||||||
|
dot = strchr(GIVE_STRADDR(vlink, name_offs), '.');
|
||||||
|
if (dot)
|
||||||
|
*dot=0;
|
||||||
|
|
||||||
|
for (number = 1; number <= 999; number++) {
|
||||||
|
BLI_snprintf(tempname, 128, "%s.%03d", GIVE_STRADDR(vlink, name_offs), number);
|
||||||
|
|
||||||
|
exists = 0;
|
||||||
|
for (link= list->first; link; link= link->next) {
|
||||||
|
if (vlink != link) {
|
||||||
|
if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) {
|
||||||
|
exists = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists == 0) {
|
||||||
|
BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BLI_addhead(ListBase *listbase, void *vlink)
|
void BLI_addhead(ListBase *listbase, void *vlink)
|
||||||
{
|
{
|
||||||
|
@ -3864,6 +3864,7 @@ void do_armbuts(unsigned short event)
|
|||||||
grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
|
grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
|
||||||
strcpy(grp->name, "Group");
|
strcpy(grp->name, "Group");
|
||||||
BLI_addtail(&pose->agroups, grp);
|
BLI_addtail(&pose->agroups, grp);
|
||||||
|
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
|
||||||
|
|
||||||
pose->active_group= BLI_countlist(&pose->agroups);
|
pose->active_group= BLI_countlist(&pose->agroups);
|
||||||
|
|
||||||
@ -5050,6 +5051,22 @@ char *get_vertexgroup_menustr(Object *ob)
|
|||||||
return menustr;
|
return menustr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void verify_poselib_posename(void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
bAction *act= (bAction *)arg1;
|
||||||
|
TimeMarker *marker= (TimeMarker *)arg2;
|
||||||
|
|
||||||
|
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_posegroup_groupname(void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
bPose *pose= (bPose *)arg1;
|
||||||
|
bActionGroup *grp= (bActionGroup *)arg2;
|
||||||
|
|
||||||
|
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
|
||||||
|
}
|
||||||
|
|
||||||
static void editing_panel_links(Object *ob)
|
static void editing_panel_links(Object *ob)
|
||||||
{
|
{
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
@ -5165,7 +5182,8 @@ static void editing_panel_links(Object *ob)
|
|||||||
if (act->active_marker) {
|
if (act->active_marker) {
|
||||||
TimeMarker *marker= poselib_get_active_pose(act);
|
TimeMarker *marker= poselib_get_active_pose(act);
|
||||||
|
|
||||||
uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change.");
|
but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change.");
|
||||||
|
uiButSetFunc(but, verify_poselib_posename, act, marker);
|
||||||
uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Library Pose from Pose Library.");
|
uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Library Pose from Pose Library.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5198,7 +5216,8 @@ static void editing_panel_links(Object *ob)
|
|||||||
bActionGroup *grp= (bActionGroup *)BLI_findlink(&pose->agroups, pose->active_group-1);
|
bActionGroup *grp= (bActionGroup *)BLI_findlink(&pose->agroups, pose->active_group-1);
|
||||||
|
|
||||||
/* active group */
|
/* active group */
|
||||||
uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,140-18-20,20, grp->name, 0, 63, 0, 0, "Displays current Pose Group name. Click to change.");
|
but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,140-18-20,20, grp->name, 0, 63, 0, 0, "Displays current Pose Group name. Click to change.");
|
||||||
|
uiButSetFunc(but, verify_posegroup_groupname, pose, grp);
|
||||||
uiDefIconBut(block, BUT, B_POSEGRP_REMOVE, VICON_X, xco+140-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Group");
|
uiDefIconBut(block, BUT, B_POSEGRP_REMOVE, VICON_X, xco+140-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Group");
|
||||||
|
|
||||||
/* set custom color set */
|
/* set custom color set */
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
@ -947,6 +948,7 @@ void action_groups_group (short add_group)
|
|||||||
sprintf(agrp->name, "Group");
|
sprintf(agrp->name, "Group");
|
||||||
|
|
||||||
BLI_addtail(&act->groups, agrp);
|
BLI_addtail(&act->groups, agrp);
|
||||||
|
BLI_uniquename(&act->groups, agrp, "Group", offsetof(bActionGroup, name), 32);
|
||||||
|
|
||||||
set_active_actiongroup(act, agrp, 1);
|
set_active_actiongroup(act, agrp, 1);
|
||||||
|
|
||||||
@ -2140,6 +2142,7 @@ static void numbuts_action ()
|
|||||||
}
|
}
|
||||||
else if (agrp) {
|
else if (agrp) {
|
||||||
strcpy(agrp->name, str);
|
strcpy(agrp->name, str);
|
||||||
|
BLI_uniquename(&( ((bAction *)data)->groups ), agrp, "Group", offsetof(bActionGroup, name), 32);
|
||||||
|
|
||||||
if (expand) agrp->flag |= AGRP_EXPANDED;
|
if (expand) agrp->flag |= AGRP_EXPANDED;
|
||||||
else agrp->flag &= ~AGRP_EXPANDED;
|
else agrp->flag &= ~AGRP_EXPANDED;
|
||||||
@ -3724,6 +3727,9 @@ void action_add_localmarker (bAction *act, int frame)
|
|||||||
BLI_addtail(&act->markers, marker);
|
BLI_addtail(&act->markers, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* validate the name */
|
||||||
|
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
|
||||||
|
|
||||||
/* sets the newly added marker as the active one */
|
/* sets the newly added marker as the active one */
|
||||||
action_set_activemarker(act, marker, 1);
|
action_set_activemarker(act, marker, 1);
|
||||||
|
|
||||||
@ -3758,8 +3764,9 @@ void action_rename_localmarker (bAction *act)
|
|||||||
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
|
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* copy name */
|
/* copy then validate name */
|
||||||
BLI_strncpy(marker->name, name, sizeof(marker->name));
|
BLI_strncpy(marker->name, name, sizeof(marker->name));
|
||||||
|
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
|
||||||
|
|
||||||
/* undo and update */
|
/* undo and update */
|
||||||
BIF_undo_push("Action Rename Marker");
|
BIF_undo_push("Action Rename Marker");
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -345,7 +346,7 @@ void poselib_add_current_pose (Object *ob, int val)
|
|||||||
/* get/initialise poselib */
|
/* get/initialise poselib */
|
||||||
act= poselib_validate(ob);
|
act= poselib_validate(ob);
|
||||||
|
|
||||||
/* validate name and get frame */
|
/* get frame */
|
||||||
frame= poselib_get_free_index(act);
|
frame= poselib_get_free_index(act);
|
||||||
|
|
||||||
/* add pose to poselib - replaces any existing pose there */
|
/* add pose to poselib - replaces any existing pose there */
|
||||||
@ -363,6 +364,9 @@ void poselib_add_current_pose (Object *ob, int val)
|
|||||||
|
|
||||||
BLI_addtail(&act->markers, marker);
|
BLI_addtail(&act->markers, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* validate name */
|
||||||
|
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loop through selected posechannels, keying their pose to the action */
|
/* loop through selected posechannels, keying their pose to the action */
|
||||||
@ -504,8 +508,9 @@ void poselib_rename_pose (Object *ob)
|
|||||||
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
|
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* copy name */
|
/* copy name and validate it */
|
||||||
BLI_strncpy(marker->name, name, sizeof(marker->name));
|
BLI_strncpy(marker->name, name, sizeof(marker->name));
|
||||||
|
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
|
||||||
|
|
||||||
/* undo and update */
|
/* undo and update */
|
||||||
BIF_undo_push("PoseLib Rename Pose");
|
BIF_undo_push("PoseLib Rename Pose");
|
||||||
|
Loading…
Reference in New Issue
Block a user