Detach Elements

69 votes
Version: 
1.0
Date Updated: 
03/23/2010
Author Name: 
Anubis

Detach all elements on multiple objects with a few options for better scene arrangement,
including convert to mesh, group by source or link to source or point helper.

Detach Elements

Additional Info: 

Please read the notes inside the code as well.

Update:
Recently asked me for installation instructions so I add macroScript.
Briefly, put Detach_Elements.ms into your scripts folder and run .mcr file once.
After that you'll find it into Tools category in your Costumize User Interface.

Version Requirement: 
any 3ds Max version
AttachmentSize
Detach_Elements.ms4.36 KB
macro_Detach_Elements.mcr386 bytes

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
itay tzafrir's picture

Automating using the script

WOW!!!

WORKS LIKE A CHARM

THANK YOU SO MUCH!!

miauu's picture

.

Save this as a .ms file.

/*
	Detach Elements v.1.0
	Author : Anubis [project3d.narod.ru]
	Created: [2010-01-18] - entire code
	Updated: [2010-03-15] - added notes
	Requirement: any 3ds Max version
	Description:
		Detach all elements on multiple objects
	Usage Notes:
		Sometime in 3ds Max 2008/2009 Undo buffer become empty
		after script usage. This come from the major undo bug in this
		Max releases, i.e. it's not related to the script code itself.
	Solution:
		Use Max Edit Hold/Fetch feature instead in 3ds Max 2008/2009.
*/
-- if Detach2Elements != undefined do
-- 	if classOf Detach2Elements == RolloutClass do
-- 		destroyDialog Detach2Elements
-- rollout Detach2Elements "Detach Elements"
(
	--// Top level Locals
	local srcObjs = #() -- source objs
	local tmpObjs = #() -- temporary
	local endObjs = #() -- for conv2Mesh
	local eleGroups = #() -- for UnGrouping
 
	local keepSource = true
	local UndoOn = false
	local isGroup = false
	local cPivot = false
	--// Functions
	fn DetachToElements obj cPivot &endObjs num:1 = (
		while obj.getNumFaces() != 0 do (
			polyop.setFaceSelection obj #{1}
			obj.selectElement()
			ele = polyop.getFaceSelection obj
			newName = (num as string)
			num += 1 -- pump up counter
			polyop.detachFaces obj ele asNode:true name:newName
			newObj = getNodeByName newName
			append endObjs newObj
			attachObjects obj newObj
		)
		if cPivot do centerPivot obj.children
	)
	mapped fn renameChildren ch = (
		ch.name = ch.parent.name + ch.name
	)
	--// UI
-- 	group "Base Options"
-- 	(
-- 		checkBox keepSource "Keep Source Objects" checked:true
-- 		checkBox UndoOn "Enable Undo" checked:false --enabled:false
-- 	)
-- 	group "New Objects"
-- 	(
-- 		checkBox outMesh "Convert to Mesh" checked:false
-- 		checkBox isGroup "Group by Source" checked:false
-- 		checkBox cPivot "Center Pivot" checked:false
-- 	)
-- 	group ">>>"
-- 	(
-- 		button detach "Detach" width:140
-- 		label feed "..."
-- 		progressbar progBar color:green
-- 	)
	--// this function must be here! (ie after UI def.)
	fn runEntirely = (
-- 		feed.text = "Detaching..."
		local total = (tmpObjs.count as string) -- total objects
		for i = 1 to tmpObjs.count do (
-- 			feed.text = "Detaching... " + (i as string) + "/" + total -- progress
			DetachToElements tmpObjs[i] cPivot endObjs
			grp = group tmpObjs[i].children name:(srcObjs[i].name + "_Elements")
			append eleGroups grp -- for UnGrouping ...
			attachObjects srcObjs[i] grp move:false -- link G to source obj.
			renameChildren grp.children -- rename
-- 			progBar.value = 100. * i / tmpObjs.count -- % progress
		)
-- 		progBar.value = 0 -- reset progressbar
-- 		feed.text = "Finalize..."
		eleGroups = for g in eleGroups where isValidNode g collect g -- important!
		if not isGroup do 
		( -- if you rid of groups...
			if not keepSource do ( -- and original objs deleted...
				local n = 1 -- get for progressBar
				for g in eleGroups do ( -- to preserve hierarchy...
					holder = point pos:g.pos name:g.name
					g.parent = holder -- replace GroupHead with Point.
-- 					progBar.value = 100. * n / eleGroups.count -- % progress
					n += 1 -- pump up counter
				)
			)
-- 			progBar.value = 0 -- reset progressbar
			ungroup eleGroups -- now ungroup all at once
		)
		if not keepSource do (delete srcObjs)
	)
	--// Events
-- 	on detach pressed do
-- 	(
-- 		feed.text = "Initialize..."
		--// filter selection
		srcObjs = for i in selection where canConvertTo i Editable_Poly collect i
		-- save your time
		if srcObjs.count == 0 then (
-- 			feed.text = "* Nothing to proceed *"
		)
		else ( --// Runtime...
			disableSceneRedraw()
-- 			feed.text = "Preparation..."
			max create mode
			setWaitCursor() -------------------
			TimeStart = timestamp()
			numObjs = objects.count
			snapshot srcObjs -- make copies...
			tmpObjs = ( -- and collect 'em
				for i = (numObjs + 1) to objects.count collect objects[i]
			)
			convertTo tmpObjs Editable_Poly
			--// the "core" in Undo context
			with undo "Detach" UndoOn ( runEntirely() )
			delete tmpObjs -- KEEP this Out Off Undo context !!!
			---------------------
			endObjs = for i in endObjs where isValidNode i collect i -- important!
-- 			if outMesh.state do convertToMesh endObjs
			select endObjs
-- 			feed.text = "Done!"
			TimeEnd = (timestamp() - TimeStart) / 1000.
			setArrowCursor() --------------------
			enableSceneRedraw()
			redrawViews()
			format "Time:\t%sec.\n" TimeEnd
		) -- end (Runtime)
-- 	) -- end (on detach pressed)
) -- end of rollout
-- createDialog Detach2Elements
itay tzafrir's picture

Automating using the script

Is there a version of the script in which it works automatically with the same settings?
I want to run it using an outside script with only the "keep source object" on, the rest should be off and press detach, without even opening the dialog

Thanks

bleras's picture

work!

Works great and its fast! tx!

Nevil's picture

Cool

Hi Panayot
Cool stuff, just a little problem when pushing the Detach button on other object after Detach the fist one the script select the parts of older detached object, you can fix that by clean the arrays holding that nodes on end of the Detach button action.
Thank you.

mahmouds12's picture

detaching but keeping same group hierarchy

hello I need to detach all elements but keeping same group hierarchy for example I have a group called "group_1" Inside it i have 3 groups inside each group some editable polys

-Group_1

    -group_A

          -EDITPOLY01

         -EDITPOLY02

         -EDITPOLY03

   -group_B

         -EDITPOLY01

         -EDITPOLY02

         -EDITPOLY03

   -group_C

         -EDITPOLY01

         -EDITPOLY02

         -EDITPOLY03

 

I need my source objs to be deleted but keep the same group hierarchy Also I have objects imported from other software which has the same name... when i try to detach elements of a selected object... the script detach another object with the same name Thanks :)
help will be appreciated :)

Anubis's picture

if you talk about Max 2012

then everything is possible, lol :)

my recent MAXScripts RSS (archive here)

ruhl's picture

freezeeeee

hey anubis,
when i'm using your script. In some time when i push Detach button max freeze and nothing happened?
I think this is a some kind of bug.

new's picture

thx

thx

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.