ZBrushCentral

Batch delete script

I’m attempting to create a simple script to batch process all subtools in a tool and delete those that are below the desired threshold. It’s mostly functional except it doesn’t execute the desired action on every subtool. It successful retains any subtools outside of the threshold, but doesn’t seem to catch all within the threshold on the first run. It has to be ran multiple times in order to catch everything. Anyone have insight on why it might be missing some?

[VarDef, pointCount]

[IButton, “Cleanup”,
[If, [IsEnabled, “Tool:SubTool:SelectUp”], [SubToolSelect, 0]]
[Loop, 999,
[Loop, 999,
[Mesh3DGet,0, , ,pointCount]
[If, (pointCount < 1000), [IPress, “Tool:SubTool:Delete”],]
[If, [IsEnabled, “Tool:SubTool:SelectDown”], [LoopExit]]
[IPress, “Tool:SubTool:SelectDown”]
]
[If, [IsEnabled, “Tool:SubTool:SelectDown”], [LoopExit]]
]
[Note, “Batch Delete Complete”]
,1.0]

Hi @HTM3d

so I fixed up your script and added some comment so you can understand better what the script is doing :

  1. note that you forget to add the tooltip in your button definition.
  2. also you just need a single loop to iterate in the subtoll list
  3. no need to have a loop of 999, just use [SubToolGetCount]
  4. use the n var of the loop so you can switch to the next subtool index.
  5. then if you have a subtool with less than 1000 points n you delete it but to no get the popup note, you can do the trick with the IKeyPress.
[VarDef, pointCount, 0]

[IButton, "???","Cleanup",
	// select the first subtool
	[SubToolSelect, 0]
	// iterate on the subtool count
	[Loop, [SubToolGetCount],
		// select the next subtool
		[SubToolSelect, n]
		// get the point count
		[Mesh3DGet,0, , ,pointCount]
		// if the point count is lesser than 1000
		[If, (pointCount < 1000), 
			// delete and remove the note popup 
			[IKeyPress, '2', [IPress, "Tool:SubTool:Delete"]]
		]
	,n]
	// batch complete :D
	[Note, "Batch Delete Complete"]
,,1]

Hope it Helps!
Nicolas

1 Like

Thanks @facelessmindz, this is great! I didn’t know about the subtool query or KeyPress action to circumvent pop-ups. Those will help immensely.

I ran your script and it functions well except that it’s running into the same issue as mine with only catching a few within the threshold each run. With enough runs, it’ll eventually catch everything. The logic appears sound (to the best of my understanding). I have no idea why it’s not executing for all subtools on the first go… I keep coming back to the ham-fisted approach of nesting it in another loop.

it works well on my side, i don’t have that issue you 'd described.
for the test i got to make it simple, so I 'd reduced the threshold to 100 points ( not 1000 like you).

well I based my tests on some polymesh3d of 14 points, and add here and there a lot of primitive that exceed 100 polys, I run the script and every polymesh3d which are smaller than 100 points, are all deleted properly.

I create a tool with many primitives and add polymesh3D so each polymesh3D only got 14 points, and are supposed to get deleted by the script.

The script select the very first subtool with [SubToolSelect, 0] before to enter in the loop, so i don’t understand that you get that problem.

or can you send me your ztl file so i can test and check what’s get wrong ?

Nicolas

Not sure then. I’m having the script run through a large amount of subtools to clean up split artifacts for 3D print.

This information is relative and mostly irrelevant, but as an example, my initial subtool count is 159 with 103 of those being artifacts needing to be deleted. First run catches 56 of them, next run catches 24, and so on until all are deleted.

I think it may be caused by the order of operations? When a subtool is deleted the next subtool down becomes selected. The next selection command would then skip that subtool on next loop. Placing the next subtool in the “else” section helped catch more, but still not cleaning up all. I’ll continue debugging.

ok, so we gonna delete from the last subtool in the stack with that script , try it and tell me if it fix the issue, but it might might have right, delete it fromt the top good change how the loop iterate in the list.

[VarDef, pointCount, 0]

[IButton, "???","Cleanup",
	// select the first subtool
	[SubToolSelect, 0]
	// iterate on the subtool count
	[VarSet, subtool, [SubToolGetCount]]
	[Loop, [SubToolGetCount],
		// select the next subtool
		[SubToolSelect, subtool]
		// get the point count
		[Mesh3DGet,0, , ,pointCount]
		// if the point count is lesser, then 1000
		[If, (pointCount < 1000), 
			// delete and remove the note popup 
			[IKeyPress, '2', [IPress, "Tool:SubTool:Delete"]]
		]
		[VarDec, subtool]
	,n]
	// batch complete :D
	[Note, "Batch Delete Complete"]
,,1]```
1 Like

This worked perfectly. Thanks for this! I actually found another solution while debugging as well. Using the select down function within the else statement worked whereas SubToolSelect did not.

[VarDef, pointCount, 0]

[IButton, “???”,“Cleanup”,
[SubToolSelect, 0]
[Loop, [SubToolGetCount],
[Mesh3DGet,0, , ,pointCount]
[If, (pointCount < 1000),
[IKeyPress, ‘2’, [IPress, “Tool:SubTool:Delete”]]
,
[IPress, “Tool:SubTool:Select Down”]
]
,n]
[Note, “Batch Delete Complete”]
,1],

Thanks again for the assistance. This has had me stumped for the last 2 days.