PDA

View Full Version : uniqueName a part


JokerMartini
03-06-2012, 03:31 PM
Is there an easier way to make a unique name for section of a name.
Example being. I have these objects in the scene

doug_guide_arm001_l_001
doug_guide_arm001_l_002
doug_guide_arm001_l_003
doug_guide_arm001_l_004

doug_guide_arm001_r_001
doug_guide_arm001_r_002
doug_guide_arm001_r_003
doug_guide_arm001_r_004

doug_guide_hip001_m_001

I collect all the objects with same guide type name
guideType = "arm"
for obj in helpers where (matchPattern obj.name pattern:("*" + guideType + "*")) collect obj
now is there an easy way to version this number up. Scanning the collected objects and incremental it by 1 leaving the 3 digit padding and then returning the new name within a function.

so ideally ill supply a function a name and it will return the unique name.

resulting in
doug_guide_arm002_l_001

3ak
03-06-2012, 03:59 PM
pat = "arm001"
execute ("select $helpers/*"+pat+"*")
for obj in selection do obj.name = replace obj.name (pat.count-1 + findstring obj.name pat) 1 "2"

JokerMartini
03-06-2012, 04:07 PM
What I came up with is more complex than it might need to be.


guideType = "spine"
exGroups = for obj in helpers where (matchPattern obj.name pattern:("*" + guideType + "*")) collect obj.name
txt = for itm in exGroups where (findString itm guideType) != undefined collect (findString itm guideType)
existingValues = #()
for v = 1 to exGroups.count do
(
ver = (substring exGroups[v] (txt[v]+guideType.count) 3) as integer + 1
newVersion = (FormattedPrint ver format:"3.3d") as string --//Adds "v" plus 3 digit padding
print newVersion
)

denisT
03-06-2012, 04:09 PM
Is there an easier way to make a unique name for section of a name.
Example being. I have these objects in the scene

doug_guide_arm001_l_001
doug_guide_arm001_l_002
doug_guide_arm001_l_003
doug_guide_arm001_l_004

doug_guide_arm001_r_001
doug_guide_arm001_r_002
doug_guide_arm001_r_003
doug_guide_arm001_r_004

doug_guide_hip001_m_001

I collect all the objects with same guide type name
guideType = "arm"
for obj in helpers where (matchPattern obj.name pattern:("*" + guideType + "*")) collect obj
now is there an easy way to version this number up. Scanning the collected objects and incremental it by 1 leaving the 3 digit padding and then returning the new name within a function.

so ideally ill supply a function a name and it will return the unique name.

resulting in
doug_guide_arm002_l_001

why is not doug_guide_arm001_l_005?

JokerMartini
03-06-2012, 04:12 PM
I first need to find the highest groupNumber before increment it by 1. Otherwise it would still be incorrect.

denisT
03-06-2012, 04:14 PM
you rule is too special to be a general. so the function needs some guidance... about the part of the name that has to be incremented.

JokerMartini
03-06-2012, 04:16 PM
why is not doug_guide_arm001_l_005?

I want to group each arm so if there are multiples arms it would go

arm001_l_001 --left collarbone
arm001_l_002 --left shoulder
arm001_l_003 --left forearm
arm001_l_004 --left wrist

arm002_r_001 --right collarbone
arm002_r_002 --right shoulder
arm002_r_003 --right forearm
arm002_r_004 --right wrist

so if i created another arm it would be

arm003_r_001 --right collarbone
arm003_r_002 --right shoulder
arm003_r_003 --right forearm
arm003_r_004 --right wrist

denisT
03-06-2012, 04:16 PM
I first need to find the highest groupNumber before increment it by 1. Otherwise it would still be incorrect.
so the function has to split a name on header, name, group index, type, and node index. after that we can talk about incrementing a part.

denisT
03-06-2012, 04:20 PM
if you have group indexes 1,2,and 5 what the next available is 3 or 6?

JokerMartini
03-06-2012, 04:22 PM
This is my format
doug_guide_spine001_m_001
doug_guide_spine001_m_002
doug_guide_spine001_m_003

katie_guide_leg001_m_001
katie_guide_leg001_m_002
katie_guide_leg001_m_003

1.Character Name
2.Control "guide" --ex: guide,bone,control etc. doesn't matter really for this.
3.Type + GroupNumber (3 digit padding)
4.Location --ex: l (left), m (middle), or r (right)
5.Node Index --UniqueName done in maxscript on point helper creation.

JokerMartini
03-06-2012, 04:23 PM
6 would be the next number.
It doesn't matter if it is perfectly incremental by 1, as long as it is unique. That is more important.

denisT
03-06-2012, 04:33 PM
This is my format

1.Character Name
2.Control "guide" --ex: guide,bone,control etc. doesn't matter really for this.
3.Type + GroupNumber (3 digit padding)
4.Location --ex: l (left), m (middle), or r (right)
5.Node Index --UniqueName done in maxscript on point helper creation.

definitely the regex might be a solution. we need to write the right one :) let's try

JokerMartini
03-06-2012, 04:34 PM
The main reason behind the whole grouping through is so i can add multiple limbs or whatever it may be and manage them in a way that I feel is best. I appreciate the help.

denisT
03-06-2012, 06:30 PM
ok...
here is a regex solution. the most complicated part was to write the right expression.

fn makeBoneRegex charname: bonename: type:#any =
(
if charname == unsupplied do charname = ".*"
if bonename == unsupplied do bonename = ".*"
type = case type of
(
#any: "[l,m,r]"
#right: "r"
#left: "l"
#middle: "m"
default: "[a-z]"
)
dotnetobject "System.Text.RegularExpressions.Regex" ("(^" + charname + "_?)(" + bonename + ")([0-9]{3}?)(_" + type + "_)([0-9]{1,}$)")
)

struct BoneStruct (node, char, name, index, type, id)
fn getBones nodes: charname: bonename: type:#any =
(
if nodes == unsupplied do nodes = objects as array

rg = makeBoneRegex charname:charname bonename:bonename type:type
for node in nodes where rg.IsMatch node.name collect
(
d = (rg.Match node.name).groups
BoneStruct node:node \
char:(trimright d.item[1].value "_") \
name:d.item[2].value \
index:(d.item[3].value as integer) \
type:d.item[4].value[2] \
id:(d.item[5].value as integer)
)
)
/*
(
delete objects
local chars = #("Chip", "Dale", "Jack")
local bones = #("arm", "leg", "spine")
local types = #("l", "m", "r")

seed 0
for k=1 to 100 do
(
name = chars[random 1 3] + "_" + bones[random 1 3] + (formattedprint (random 1 6) format:"03d") + "_" + types[random 1 3] + "_"
box name:(uniquename name)
)
)
-- print all chip's right arms
print (getBones charname:"Chip" bonename:"arm" type:#right)
-- print all dale's bones
print (getBones charname:"Dale")
*/


when we found all bones that matches the pattern it's easy to sort them by index and find the highest. after that there's no problem to make the unique name

JokerMartini
03-06-2012, 06:46 PM
While developing this and messing around with different ideas of my own that was something i was trying to grasp and understand as well. Meaning the best way to right a solution that would work well. I was unable to come up with a solid solution myself. I did begin reading up on the regex stuff once you mentioned it. I was un aware of what that brings to maxscript. It's useful to know that is available. I'll check out what you've written here. I'm excited to get this working and implemented. I appreciate the time you spent working on this Denis. I'll let you know how it goes.

JokerMartini
03-06-2012, 07:29 PM
So I'm not entirely sure how to use what is written here.

Say i run what you've written and uncomment the loop which creates boxes.


ok so now I want to create an additional box but with a unique name. Where does that happen?

Do i increment the index?

denisT
03-06-2012, 07:49 PM
# you got all bones as structure
# find item with maximum index (let's call it b)
# make new(unique) name as:

uniquename (b.char + "_" + b.name + (formattedprint (b.index+1) format:"03d") + "_" + b.type + "_")

that's it

JokerMartini
03-06-2012, 08:11 PM
so I did something like this



exBones = (getBones charname:"Dale" bonename:"leg")
b = exBones[exBones.count]
newPt = point name:(uniquename (b.char + "_" + b.name + (formattedprint (b.index+1) format:"03d") + "_" + b.type + "_"))

JokerMartini
03-06-2012, 08:15 PM
for bug sake purposes it bugs out if no bone exists. using the code i pasted above.

denisT
03-06-2012, 08:53 PM
so I did something like this



exBones = (getBones charname:"Dale" bonename:"leg")
b = exBones[exBones.count]
newPt = point name:(uniquename (b.char + "_" + b.name + (formattedprint (b.index+1) format:"03d") + "_" + b.type + "_"))


you have to sort then exBones by index first

JokerMartini
03-06-2012, 10:47 PM
This is great. I've got it working. Thanks Denis
It took a little understanding and then it all came together.

CGTalk Moderation
03-06-2012, 10:47 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.