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: 

Drilling Macro

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
Benjuarez13P9DBD
1914 Views, 11 Replies

Drilling Macro

Hello all,

This may be a far fetched request but just trying to make my life easier here.  I am programming thermoforming production molds in aluminum and therefore must drill a lot of .025 holes to allow vacuum to pass through without deforming the part.  What I have been doing is manually splitting the toolpath every 10 holes or so and inserting a line of code in the program to go and do a tool length breakage test on a renishaw probe because when drilling 400+ holes it takes a long time to try and find where it broke at in a drill that small.  My question is, is there a way to write a macro to have powermill sort the toolpath along the x direction two way in y, but then split the toolpath based on a specified number of holes and then create different toolpaths for the specified number? 

11 REPLIES 11
Message 2 of 12

Hey there,

 

As for the ordering of the toolpath, in the toolpath dialog menu under or, you can have the drill move in whatever direction you would like.

 

For the macro to split, give me a few hours to figure this one out. This one will be a bit tough lol.

 

Thank you

Message 3 of 12
barr.jarryd
in reply to: barr.jarryd

So this macro is not 100% what you are looking for but I'm sure it will help speed up the process.

 

This will take your feature set, reorder it, then split it into segments of 10 features per set. You can change that amount yourself via the code.

 

Hopefully this helps you out a bit.

 

//-----------------------------------------------------------------//
// this macro was written by @barr.jarryd. Original macro          //
// included references to three additional macros. This way the    //
// code does not repeat itself, and there                          //
// is only one file and one bit of code to edit should there ever  //
// be a change to the macro.                                       //
//-----------------------------------------------------------------//
//                          UPDATES                                //
// detailed updates go here. include 'who, when, what'             //
//-----------------------------------------------------------------//


//Sort active featureset in the x direction 2 ways
EDIT FEATURESET "1" SORT "xz"
ACTIVATE FEATURESET "1"

// Create an empty list
STRING LIST featList = {}

// Fill list with feature names from featureset 1
FOREACH f in components(entity('featureset','1')) {

	INT Number = add_last(featList, f.name)

}

//Start Selecting Features

INT Count = 0

WHILE size(featList) > 10 {

	WHILE $Count < 10 {

		// Pull features from list to select 
		STRING select = remove_first(featList)
		EDIT FEATURESET "1" SELECT $select
		$Count = $Count + 1

	}
			//Once you hit 10 selected copy into new Featureset and delete the one in the existing. Change this value if you want to increase the amount of features to split by.
			IF $Count == 10 {

				COPY FEATURESET "1" SELECTED
				DELETE FEATURESET "1" SELECTED
				$Count = 0

					
			}

}

//Once the sets ahve been sorted, rename the sets for use
					
STRING newName = ""
INT i = 1
FOREACH fs in FOLDER('FeatureSet') {
	$newName = $fs.name + "-"
	RENAME FEATURESET $fs.name $newName							
}

FOREACH fs in FOLDER('FeatureSet') {
	$newName = $i
	RENAME FEATURESET $fs.name $newName						
	$i = $i + 1
}

MESSAGE INFO "Begin Programming"
Message 4 of 12

Thanks! I've went through and changed a few things to make it work more customized to what I have setup but you definitely gave me a huge jump towards what I was looking for. Still trying to get into macro programming some more, I appreciate the work you put in for me

Message 5 of 12

Not a problem at all. Just happy I could help.
Message 6 of 12
Anonymous
in reply to: Benjuarez13P9DBD

Well @barr.jarryd kind of beat me to it but I stayed up late last night taking a stab at this. I'll post my version because it does a few things differently. Maybe you can merge the too. Mine will take an existing monolithic drill path and create individual toolpaths with only the specified number of hole features. This code doesn't assume a featureset, it grabs it directly from the toolpath. It also doesn't assume all of the features in that featureset were used for the toolpath. You could probably add a STRING  argument to the main function to pass in the toolpath name so you didn't have to manually change each time.

FUNCTION Main() {
	
	// Change this to the toolpath name
	STRING $toolpathName = "MyDrillPathName"
	
	// Change this to be the number of holes to split that path at
	INT $holeSplitValue = 10
	
	// Setup the variables
	BOOL $entityExists = FALSE
	STRING $featureSetName = ""
	INT $featureCount = 0

	// Check to see if the toolpath exists
	CALL DoesEntityNameExist('Toolpath', $toolpathName, $entityExists)
	IF $entityExists == FALSE {
		// Not an existing toolpath. Abort!
		MACRO ABORT
	}
	// Check to see if it's a drilling strategy
	IF entity('Toolpath', 'MyDrillPathName').Strategy == 'drill' {
		
		// Activate the path so it'll activate featuresset and
		// also sellect the features used for calculating the path
		ACTIVATE TOOLPATH $toolpathName
		
		// Get the featureset name
		$featureSetName = entity('Toolpath', $toolpathName).FeatureSet.Name
		
		// Create a STRING LIST to store the new generated featureset names
		STRING LIST $tempFeaturesetNameList = {}
		
		// Get the next safe name for a generates featureset
		STRING $nextAvailableName = ""
		CALL GetSafeEntityName('FeatureSet', $featureSetName, $nextAvailableName)
			
		// We make a copy of the orignal featureset so we omly get the features
		// that were used during the calculation of the path
		COPY FEATURESET $featureSetName SELECTED
		ACTIVATE FEATURESET $nextAvailableName
		
		// Loop through and split the featuresets up by the specified
		// number of features. This part was writen at 3am so it's pretty
		// bad and the logic could probably be cleaned up a lot
		INT $holeCount = 0
		FOREACH $name IN extract(components(entity('featureset', $nextAvailableName)),'name') {
			// Check to see if we've reached or split value yet. If so
			// we'll break out those features into a new featureset
			IF $holeCount == $holeSplitValue {
				$holeCount = 0
				STRING $tempName = ""
				CALL GetSafeEntityName('FeatureSet', $nextAvailableName, $tempName)
				COPY FEATURESET $nextAvailableName SELECTED
				//$nextAvailableName = $tempName
				ACTIVATE FEATURESET $nextAvailableName
				EDIT FEATURESET $nextAvailableName DESELECT ALL
				INT $i = add_last($tempFeaturesetNameList, $tempName)
			}
			// Continue sellecting the features 
			EDIT FEATURESET $nextAvailableName SELECT $name
			$holeCount = $holeCount + 1	
			
		}
		// This is nasty but, because of the bad logic above, we'll
		// still have the remaining selected holes that didn't reached
		// our split value so we'll do one final split
		STRING $tempName = ""
		CALL GetSafeEntityName('FeatureSet', $nextAvailableName, $tempName)
		COPY FEATURESET $nextAvailableName SELECTED
		INT $i = add_last($tempFeaturesetNameList, $tempName)
		
		// Get the next safe name for a toolpath
		STRING $newPathName = ""
		$newPathName = $toolpathName
		//CALL GetSafeEntityName('Toolpath', $toolpathName, $newPathName)
		
		//Loop through the copied featureset names and generate a drill
		//path, based on your existing one
		FOREACH $copiedFeatureset IN $tempFeaturesetNameList {
			ACTIVATE TOOLPATH $newPathName FORM TOOLPATH
			STRING $tempName = ""
			CALL GetSafeEntityName('Toolpath', $newPathName, $tempName)
			EDIT TOOLPATH $newPathName CLONE
			$newPathName = $tempName
			ACTIVATE TOOLPATH $newPathName FORM TOOLPATH
			
			ACTIVATE Featureset $copiedFeatureset
			EDIT TOOLPATH $newPathName CALCULATE
			
			$newPathName = $tempName
		}
	}
	
}

// Checks to see if an entity's name exists
FUNCTION DoesEntityNameExist(STRING entityType, STRING entityName, OUTPUT BOOL exists) {
	$exists = entity_exists($entityType, $entityName)
}

// Returns the next available safe name for an entity
FUNCTION GetSafeEntityName(STRING entityType, STRING baseName, OUTPUT STRING safeName) {
	$safeName = new_entity_name($entityType, $baseName)
}

Your next problem is going to be injecting your probe code in between each path. In the old Ductpost there was a feature where you could create a test block between the paths (in the NCProgram) and have a certain function do something with it in the written NC. It was years ago and I never got it to work. If you've already got that part covered, cool.

Message 7 of 12
Anonymous
in reply to: Anonymous

I reread what I wrote and it could've been worded better! It kind of sounded like a jab at @barr.jarryd 's code, with all of that "doesn't assume" crap. That was not at all how I meant it! So I just want to say I'm sorry if that's how it was received.

Message 8 of 12
barr.jarryd
in reply to: Anonymous

Its all good man lol.

 

I understood what you meant. No offense taken.

 

Yours is for sure more indepth than mine.

Message 9 of 12
Anonymous
in reply to: barr.jarryd

No offense is good, thanks!

 

The Ductpost function I mentioned earlier is named ppfun (a less mature person would snicker at that). It looks like it exists in PMPost, as well.

https://forums.autodesk.com/t5/powermill-forum/nc-text-blocks/td-p/6999740 

That thread has a screenshot of a ppfun set up in the PMPost software. I don't have the Ductpost documentation here at home but I looked at it at work today and it gives a short description on its usage. I forgot to bring it home, unfortunately. I'll bring it home tomorrow and post a screen cap of the section that talks about it. 

Message 10 of 12
barr.jarryd
in reply to: Anonymous

Not going to lie, I got a good chuckle at the name haha.

 

I'll take a deeper look into that when I get home after work today. Thanks for the info!

Message 11 of 12
Anonymous
in reply to: Anonymous

There's are several bugs in my code! The first is I have the starting path name hardcoded in one spot, instead of using the variable that's at the top of the macro.

// Check to see if it's a drilling strategy
	IF entity('Toolpath', 'MyDrillPathName').Strategy == 'drill' {

// Should be

// Check to see if it's a drilling strategy
	IF entity('Toolpath', $toolpathName).Strategy == 'drill' {

And then the most embarrassing one is that Activating the toolpath will not select the features if every hole was used to calculate the drill path. It only selects them if a subset of the hole features were used, which is the only way I tested it!

 

I don't have the time right now but I'll go back and fix those things, in case some future person tries to use it. 

Message 12 of 12
Anonymous
in reply to: Anonymous

I was going to go to bed but it didn't take long to fix. No more hardcoded name and I check to see if the copied featureset is empty and, if it is, I delete it and use the original featureset.

FUNCTION Main() {
	// Change this to the toolpath name
	STRING $toolpathName = "MyDrillPathName"
	// Change this to be the number of holes to split that path at
	INT $holeSplitValue = 10
	
	// Setup the variables
	BOOL $entityExists = FALSE
	STRING $featureSetName = ""
	INT $featureCount = 0

	// Check to see if the toolpath exists
	CALL DoesEntityNameExist('Toolpath', $toolpathName, $entityExists)
	IF $entityExists == FALSE {
		// Not an existing toolpath. Abort!
		MACRO ABORT
	}
	// Check to see if it's a drilling strategy
	IF entity('Toolpath', $toolpathName).Strategy == 'drill' {
		
		// Activate the path so it'll activate featuresset and
		// also sellect the features used for calculating the path
		ACTIVATE TOOLPATH $toolpathName
		
		// Get the featureset name
		$featureSetName = entity('Toolpath', $toolpathName).FeatureSet.Name
		
		// Create a STRING LIST to store the new generated featureset names
		STRING LIST $tempFeaturesetNameList = {}
		
		// Get the next safe name for a generates featureset
		STRING $nextAvailableName = ""
		CALL GetSafeEntityName('FeatureSet', $featureSetName, $nextAvailableName)
			
		// We make a copy of the orignal featureset so we omly get the features
		// that were used during the calculation of the path
		COPY FEATURESET $featureSetName SELECTED
		
		// Check to see if the copied featureset has any items
		// If it doesn't, we know every featureset was used to
		// calculate the drill path
		REAL $featureCount = entity('FeatureSet', $nextAvailableName).num_items
		IF $featureCount == 0 {
			// It's empty and we need to deal with that fact
			DELETE FEATURESET $nextAvailableName
			$nextAvailableName = $featureSetName
		}
		ACTIVATE FEATURESET $nextAvailableName
		
		// Loop through and split the featuresets up by the specified
		// number of features. This part was writen at 3am so it's pretty
		// bad and the logic could probably be cleaned up a lot
		INT $holeCount = 0
		FOREACH $name IN extract(components(entity('featureset', $nextAvailableName)),'name') {
			// Check to see if we've reached or split value yet. If so
			// we'll break out those features into a new featureset
			IF $holeCount == $holeSplitValue {
				$holeCount = 0
				STRING $tempName = ""
				CALL GetSafeEntityName('FeatureSet', $nextAvailableName, $tempName)
				COPY FEATURESET $nextAvailableName SELECTED
				//$nextAvailableName = $tempName
				ACTIVATE FEATURESET $nextAvailableName
				EDIT FEATURESET $nextAvailableName DESELECT ALL
				INT $i = add_last($tempFeaturesetNameList, $tempName)
			}
			// Continue sellecting the features 
			EDIT FEATURESET $nextAvailableName SELECT $name
			$holeCount = $holeCount + 1	
			
		}
		// This is nasty but, because of the bad logic above, we'll
		// still have the remaining selected holes that didn't reached
		// our split value so we'll do one final split
		STRING $tempName = ""
		CALL GetSafeEntityName('FeatureSet', $nextAvailableName, $tempName)
		COPY FEATURESET $nextAvailableName SELECTED
		INT $i = add_last($tempFeaturesetNameList, $tempName)
		
		// Get the next safe name for a toolpath
		STRING $newPathName = ""
		$newPathName = $toolpathName
		//CALL GetSafeEntityName('Toolpath', $toolpathName, $newPathName)
		
		//Loop through the copied featureset names and generate a drill
		//path, based on your existing one
		FOREACH $copiedFeatureset IN $tempFeaturesetNameList {
			ACTIVATE TOOLPATH $newPathName FORM TOOLPATH
			STRING $tempName = ""
			CALL GetSafeEntityName('Toolpath', $newPathName, $tempName)
			EDIT TOOLPATH $newPathName CLONE
			$newPathName = $tempName
			ACTIVATE TOOLPATH $newPathName FORM TOOLPATH
			
			ACTIVATE Featureset $copiedFeatureset
			EDIT TOOLPATH $newPathName CALCULATE
			
			$newPathName = $tempName
		}
	}
}

// Checks to see if an entity's name exists
FUNCTION DoesEntityNameExist(STRING entityType, STRING entityName, OUTPUT BOOL exists) {
	$exists = entity_exists($entityType, $entityName)
}

// Returns the next available safe name for an entity
FUNCTION GetSafeEntityName(STRING entityType, STRING baseName, OUTPUT STRING safeName) {
	$safeName = new_entity_name($entityType, $baseName)
}

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

Post to forums  

Autodesk Design & Make Report