Community
PowerMill Forum
Welcome to Autodesk’s PowerMill Forums. Share your knowledge, ask questions, and explore popular PowerMill topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Needing macro help with proper use and reference of $tool.type ....,

23 REPLIES 23
SOLVED
Reply
Message 1 of 24
stheroux
1834 Views, 23 Replies

Needing macro help with proper use and reference of $tool.type ....,

Using tool.xml user menu with multiple selection function, I am stuck on how to find all $tool.types in folder 'tool'.

Then based on results, create individual folders (eg. BallNose, TipRad, TippedDisc....,) for found $tool.types and move each tool.type to corresponding tool.type folder created.

 

 

 

23 REPLIES 23
Message 2 of 24
urizenYHS3W
in reply to: stheroux

// Make a string expression for accessing all the tools
ENTITY LIST tools = folder('tool')
// Get tool type names in current language
STRING LIST Tt_names = values(tools[0].Type)
// Get the tool types used
STRING LIST Ttypes = remove_duplicates(extract(tools,'Type'))

FOREACH t IN Ttypes {
  // get list of all tools of given type
  ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name')
  // get name of tool type in current language
  INT type_id = tools_of_type[0].Type
  STRING Type_name = Tl_names[type_id]
  // Create a folder if it doesn't already exist
  STRING Folder_name = "Tool\$Type_name"
  IF NOT folder_exists(fname) {
    CREATE FOLDER Tool $Type_name
  }
  // Move the tools to the folder
  FOREACH tt IN tools_of_type {
    EDIT FOLDER $Folder_name INSERT $tt.Name Last
  }
}

Something like the above not tested so you may have to debug it.

 

Message 3 of 24
stheroux
in reply to: urizenYHS3W

Thank you @urizenYHS3W  for getting me on the right path. I did a basic copy and paste...,

I'm trying  to get this macro to function using "selected tools" only. Function in BLUE.

 

Running macro debug through tool.xml menu, errs right away on line 1 "Variable missing" . I use this same code

on all my other tool macros and works fine..., Gets through it if I run macro without debugger. Should I be modifying this Function as it seems other than string selected, the rest is redundant?

 

If I delete Function from Macro and allow macro to pick all tools , I get an error on line 8

error.PNG

Not knowing what to fix on line 8 I can't debug further. Any additional help would be greatly appreciated.

 

Function Main( STRING $Selected ) {
STRING LIST $ToolNames = {}
CALL Get_Tool_List($Selected, $ToolNames)

//string expression for accessing all the tools
ENTITY LIST tools = folder('tool')
// Get tool type names in current language
STRING LIST Tt_names = values(tools[0].Type)
// Get the tool types used
STRING LIST Ttypes = remove_duplicates(extract(tools,'Type'))

FOREACH tl IN $Tt_names {
// get list of all tools of given type
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name')
// get name of tool type in current language
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
// Move the tools to the folder

FOREACH tt IN $tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}
}
}
Function Get_Tool_List(
STRING $Selected
OUTPUT STRING LIST $Selected_Tools
)
{
If $powermill.Status.MultipleSelection.total == 0 OR $powermill.Status.MultipleSelection.First {
IF NOT member(project._keys,"Multiple_Selected_Names") {
EDIT PAR CREATE STRING "Multiple_Selected_Names"
}
$Project.Multiple_Selected_Names = ""
} ELSE {
$Project.Multiple_Selected_Names = $Project.Multiple_Selected_Names + "\"
}
$Project.Multiple_Selected_Names = $Project.Multiple_Selected_Names + $Selected
IF NOT($powermill.Status.MultipleSelection.Last or $powermill.Status.MultipleSelection.total == 0) {
MACRO ABORT
}

$Selected_Tools = TOKENS($Project.Multiple_Selected_Names, "\")

}

 



 

Message 4 of 24
urizenYHS3W
in reply to: stheroux

Needs to be split:

STRING LIST Ttypes = extract(tools,'Type')
INT num = remove_duplicates(Ttypes)
Message 5 of 24
stheroux
in reply to: urizenYHS3W

Thanks again @urizenYHS3W . Made the suggested changes ...

Populates tools list and lists all possible tool.types available to powermill then line 6 generates error.

 

Is there a way, on line 4, to list only the $tool.types in folder 'tool' or in the entity list 'tools'  or is there not enough available information acquired at this point to give a result and I have to get past this line 6 hurtle to get there?

 

I find it odd that  tool.type so far is represented as both 

(STRING) = "End Mill" in Ttnames and as (ENUM) Type = tip_radiused in (TOOL)..., so many names!.. what to reference? Can anything be done using (ENUM)?

 

Debug.PNG

 

// Make a string expression for accessing all the tools
ENTITY LIST tools = folder('tool')
// Get tool type names in current language
STRING LIST Tt_names = values(tools[0].Type)
// Get the tool types used
STRING LIST Ttypes = extract(tools,'Type')
INT num = remove_duplicates(Ttypes)
FOREACH t IN Ttypes {
// get list of all tools of given type
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name')
// get name of tool type in current language
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
}
// Move the tools to the folder
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}

Message 6 of 24
stheroux
in reply to: stheroux

..sorry had a copy paste error there. 

I find it odd that  tool.type so far is represented as both 

(STRING) = "End Mill" in Ttnames and as (ENUM) Type = end_mill in (TOOL)..., so many names!.. what to reference? Can anything be done using (ENUM)?

Message 7 of 24
urizenYHS3W
in reply to: stheroux

The values() method returns the data in the appropriate natural language, and in human readable terms. So you'll get the names in German, French, Chinese or whatever. If you are satisfied with the enum names then don't do the conversion.

Message 8 of 24
stheroux
in reply to: urizenYHS3W

Thank you for the clarification. I do prefer your appropriate natural language result much more than the ENUM names, was just confused why there are 2 different results for the same thing. Now that I understand why code is the way it is , I still need help getting past this line of code STRING LIST Ttypes = extract(tools,'Type').

ERROR 'Type mismatch assigning 'Type to parameter'. 

No matter how much troubleshooting I try on this line, I'm getting nowhere.

I've never been successful getting tool.type to work in a macro other than the basic IF $Tool.Type == 'end_mill' or IF $Tool.Type != 'ball_nosed'. 

Getting list of tool.types in folder'tool' as result is much harder than I anticipated it would be ...let alone removing duplicate entities which I hadn't even realized would need be addressed.


ENTITY LIST tools = folder('tool')  OK
STRING LIST Tt_names = values(tools[0].Type)  OK 
STRING LIST Ttypes = extract(tools,'Type') --- At a loss --->
INT num = remove_duplicates(Ttypes) <----

Message 9 of 24
urizenYHS3W
in reply to: stheroux

STRING LIST Ttypes = apply(tools,'string(Type)') 

Type checking appears to be too strict. Type is an ENUM which converts to a string but isn't. The above should work as it explicitly converts the Type to a string by applying the string function to Type.

 

Message 10 of 24
stheroux
in reply to: urizenYHS3W

Thanks again, again, again @urizenYHS3W , that did the trick.

But as expected, I am unable to troubleshoot the next line to get it to work.

I've tried modifying the expression to be able to get eval but not getting anywhere... all listed below.

I have very similar code I use successfully 

STRING LIST $tr = extract($filter(folder('tool'), "type == '${t}' )",'tool')

but doesn't function as an ENTITY LIST.

Any additional help/guidance would be fantastic and greatly appreciated.

 

ENTITY LIST tools = folder('tool') OK
STRING LIST Tt_names = values(tools[0].Type) OK
STRING LIST Ttypes = apply(tools,'string(Type)') OK
INT old = remove_duplicates(Ttypes) OK
FOREACH t IN Ttypes { OK
ENTITY LIST tools_of_type = extract(filter(tools,'Type==t'),'Name') ORIGINAL PROVIDED CODE

ENTITY LIST tools_of_type = extract(filter(tools,'type==t'),'Name')

ENTITY LIST tools_of_type = extract(filter(tools,'Type == t'),'Name')

ENTITY LIST tools_of_type = extract(filter(tools,'type == t'),'Name') 

ENTITY LIST tools_of_type = extract(filter('tools','Type==t'),'Name')

ENTITY LIST tools_of_type = extract(filter('tools','type==t'),'Name')

ENTITY LIST tools_of_type = extract(filter('tools','Type == t'),'Name')

ENTITY LIST tools_of_type = extract(filter('tools','type == t'),'Name')

ENTITY LIST tools_of_type = extract(filter('tools',"type == 't'"),'Name')
ENTITY LIST tools_of_type = extract(filter(folder('tool'),'Type==t'),'Name') with every variation above

 

 

Message 11 of 24
urizenYHS3W
in reply to: stheroux

FOREACH t IN Ttypes {
STRING expr = "Type=='"+string(t)+"'"
ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')
Message 12 of 24
stheroux
in reply to: urizenYHS3W

Thank you @urizenYHS3W for helping me inch my way there. What a learning curve..,

STRING expr = "Type == '"+string(t)+"'"

This Code is returning (STRING) expr = "Type == 'tip_radiused'"

Which I figure is extracted from current (STRING)t in (LIST)Ttypes.

ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')

This line is returning error "Cannot create entity using:"

I'm confused where this is going.  Creating a (LIST) by extracting information by filtering a combination of 

both $tools and $expr and assigning a Name?

What should the code be returning as (LIST) = ??? from the extracted/filtered .name 

Figure if I know this, it could possibly help me troubleshoot it easier..., no clue

Is it trying to match current $Ttype to tools with that tool.type and add to list? Just incase if so, in $tools, (ENUM) Type = tip_radiused, not "Type == 'tip_radiused'" . Would this be affecting something? If no, any ideas would be fantastic!

 

ENTITY LIST tools = folder('tool')
STRING LIST Tt_names = values(tools[0].Type)
STRING LIST Ttypes = apply(tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH t IN Ttypes {
STRING expr = "Type == '"+string(t)+"'"
ENTITY LIST tools_of_type = extract(filter(tools,expr),'Name')
INT type_id = tools_of_type[0].Type
STRING Type_name = Tl_names[type_id]
// Create a folder if it doesn't already exist
STRING Folder_name = "Tool\$Type_name"
IF NOT folder_exists(fname) {
CREATE FOLDER Tool $Type_name
}
// Move the tools to the folder
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}

 

Message 13 of 24
urizenYHS3W
in reply to: stheroux

Sorry I'm not thinking

ENTITY LIST tools_of_type = filter(tools,expr)

You just want the tools of the specific type not their names.

Message 14 of 24
stheroux
in reply to: urizenYHS3W

I can see the end of the script now before erring..., thank you @urizenYHS3W .

 

INT type_id = tools_of_type[0].Type  This code is returning (INT) type_id = 0, NEXT LINE

STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"

As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed" 

I don't know if the problem is type_id = 0 or if Type_name should be looking at something other than Tt_names since

Tt_names returns every possible powermill tool even if not in current project. Should I be referencing Ttypes since that list only has tools found in project?

Otherwise I can soldier on through the macro and it creates the folder with the wrong name due to above problem but errs trying to add tools to the folder. Guessing because there are no "end_mills" in project !? Or possibly problem with last line of code !?

Capture.PNG

 

ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists($Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}

 

Message 15 of 24
Anonymous
in reply to: stheroux

Replace  

EDIT FOLDER $Folder_name INSERT $tt.Name Last

with          

STRING Cmd="EDIT FOLDER '"+$Folder_Name+"' INSERT '"+pathname($T)+"' LAST"
 DoCommand $Cmd

 

FUNCTION MAIN {
   IF size(folder('tool')) == 0 {
      RETURN
   }
   STRING LIST FolderNames=values(folder('tool')[0].Type)
   STRING Cmd=''
   FOREACH T in folder('tool') {
      STRING NewFolder='Tool\'+$FolderNames[int($T.Type)]
      IF NOT folder_exists($NewFolder) {
         $Cmd="CREATE folder 'Tool' '"+$FolderNames[int($T.Type)]+"'"
         DoCommand $Cmd
      }
      IF dirname(pathname($T)) != $NewFolder {
         $Cmd="EDIT FOLDER '"+$NewFolder+"' INSERT '"+pathname($T)+"' LAST"
         DoCommand $Cmd
      }
   }
Message 16 of 24
stheroux
in reply to: Anonymous

Thank you for helping @Anonymous .

I don't know if this solves folder naming issue or not as I silll have to address what it wrong with 

INT type_id = tools_of_type[0].Type  This code is returning (INT) type_id = 0, NEXT LINE

STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"

As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed" 

 

The script you attached works perfectly to do the same job and I will definitely hang on to that code but it's light years ahead of my current coding abilities.  I'm learning as I go and finally wrapping my head around what @urizenYHS3W  has been kind enough to school me on which I am finding to be very advanced . I'm aiming to finish the original script if it kills me. If you have a solution for above issue I will gladly try it!!

Thank you.

Capture.PNG

ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists($Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}

 

 

 

Message 17 of 24
Anonymous
in reply to: stheroux

My macro in PM 2017 Standard working:

1.Before -lang= english1.Before -lang= english2.After2.After3. change lang hungarian3. change lang hungarian

There is no Hungarian translation to turning tools,
will remain in English

- In

Message 18 of 24
stheroux
in reply to: Anonymous

Yes @Anonymous  your macro works perfectly in powermill 2020 as well.

The script you attached works perfectly to do the same job and I will definitely hang on to that code but it's light years ahead of my current coding abilities.  I'm learning as I go and finally wrapping my head around what @urizenYHS3W  has been kind enough to school me on which I am finding to be very advanced . I'm aiming to finish the original script if it kills me. If you have a solution for below issue I will gladly try it!!

 

INT type_id = tools_of_type[0].Type  This code is returning (INT) type_id = 0, NEXT LINE

STRING Type_name = Tt_names[Type_id] Is returning (STRING) Type_name = "End Mill"

As per screenshot below, should it not be returning (STRING) Type_name = "Ball Nosed" 

I don't know if the problem is type_id = 0 or if Type_name should be looking at something other than Tt_names since

Tt_names returns every possible powermill tool even if not in current project. Should I be referencing Ttypes since that list only has tools found in project?

Capture.PNG

ENTIRE MACRO >>>

ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
STRING LIST $Ttypes = apply($tools,'string(Type)')
INT old = remove_duplicates(Ttypes)
FOREACH $t IN $Ttypes {
STRING $expr = "Type == '"+string(t)+"'"
ENTITY LIST $tools_of_type = filter(tools,expr)
INT type_id = tools_of_type[0].Type
STRING Type_name = Tt_names[Type_id]
STRING Folder_name = "$Type_name"
IF NOT folder_exists(Folder_name) {
CREATE FOLDER Tool $Type_name
}
FOREACH tt IN tools_of_type {
EDIT FOLDER $Folder_name INSERT $tt.Name Last
}
}

Message 19 of 24
Anonymous
in reply to: stheroux

Thank you for your good opinion, but I think the difference between our knowledge is much smaller than you think.

 

I tried to keep as much of the original code as possible, this is a working version:

ENTITY LIST $tools = folder('tool')
STRING LIST $Tt_names = values($tools[0].Type)
// The apply() FUNCTION not working in PM2017
//STRING LIST $Ttypes = apply($tools,'string(Type)')
// Begin apply() replacement
STRING LIST $Ttypes= {}
FOREACH T IN folder('tool') {
   INT I=add_last($Ttypes,string($T.Type))
}
// End apply() replacement for PM2017

INT old = remove_duplicates(Ttypes)

FOREACH $t IN $Ttypes {
   STRING $expr = "Type == '"+ $t +"'"
   ENTITY LIST $tools_of_type = filter(tools,expr)
   INT type_id = int($tools_of_type[0].Type)
   STRING Type_name = $Tt_names[$Type_id]
   STRING Folder_name = $Type_name
   IF NOT folder_exists('Tool\'+Folder_name) {
      CREATE FOLDER Tool $Type_name
   }
   FOREACH tt IN tools_of_type {
      IF dirname(pathname($tt)) != 'Tool\'+Folder_name {
         STRING Cmd='EDIT FOLDER "Tool\'+$Folder_name+'" INSERT "'+pathname($tt)+'" Last'
         DoCommand $Cmd
      }
   }
}

Of course, you can safely delete the replacement code by restoring the original apply () function

Message 20 of 24
stheroux
in reply to: Anonymous

Made suggested changes. Had missed a change to code INT type_id = int($tools_of_type[0].Type)

Works perfect now.

 

This is the code I said was beyond me.... all the $cmd stuff is still new to me.

 

FUNCTION MAIN {
IF size(folder('tool')) == 0 {
RETURN
}
STRING LIST FolderNames=values(folder('tool')[0].Type)
STRING Cmd=''
FOREACH T in folder('tool') {
STRING NewFolder='Tool\'+$FolderNames[int($T.Type)]
IF NOT folder_exists($NewFolder) {
$Cmd="CREATE folder 'Tool' '"+$FolderNames[int($T.Type)]+"'"
DoCommand $Cmd
}
IF dirname(pathname($T)) != $NewFolder {
$Cmd="EDIT FOLDER '"+$NewFolder+"' INSERT '"+pathname($T)+"' LAST"
DoCommand $Cmd
}
}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report