select and detach vertices using maxscript

Hello, is there a way to select certain vertices and detach them to new object using maxscript?

I have following geometry merged together (called boxes) and I would like to detach one of them to new object.

I would like to select all vertices of this geometry, where X-axis is possitive (right box) or negative (left box) and detach them to new object.
How can I do that?

Thanks!

 

Comments

Comment viewing options

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

.

(
	global rol_detachByXpos
	try(destroyDialog rol_detachByXpos)catch()
	rollout rol_detachByXpos "Detach by X pos"
	(
		local poDetachVerts = polyop.detachVerts
		local poGetVert = polyop.getVert
 
		button btn_detachPosX "Detach positive X" width:140
		button btn_detachNegX "Detach negative X" width:140
 
		function DetachVertsByXpos xSide: =
		(
			if selection.count != 0 do
			(
				selObjsArr = selection as array
				for o in selObjsArr where classOf o == Editable_Poly do
				(
					vertsCnt = o.numverts
					posXBA = #{}
					negXBA = #{}
					for v = 1 to vertsCnt do
					(
						vPos = poGetVert o v
						if vPos.x > 0 do posXBA[v] = true
						if vPos.x < 0 do negXBA[v] = true
					)
					case xSide of
					(
						#positive:
						(
							if not posXBA.isEmpty do
							(
								poDetachVerts o posXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
							)
						)
 
						#negative:
						(
							if not negXBA.isEmpty do
							(
								poDetachVerts o negXBA delete:true asNode:true name:(o.name + "_detachedNegativeX") node:o
							)
						)
					)
				)
			)
		)
 
		on btn_detachposX pressed do
		(
			DetachVertsByXpos xSide:#positive
		)
		on btn_detachNegX pressed do
		(
			DetachVertsByXpos xSide:#negative
		)
	)
	createdialog rol_detachByXpos 
 
)
zwrtron's picture

Thank you

Working like a charm exactly like I except.
But any chance to make it work on plane for example? Like it cuts plane in half which has edge in the middle (pos 0)
Figure:
https://i.imgur.com/9QKVTXl.png
Thank you so much!

miauu's picture

.

Try this using Detach by Face:

(
	global rol_detachByXpos
	try(destroyDialog rol_detachByXpos)catch()
	rollout rol_detachByXpos "Detach by X pos"
	(
		local poDetachVerts = polyop.detachVerts
		local poDetachFaces = polyop.detachFaces
		local poGetVert = polyop.getVert
		local poGetFacesUsingVert = polyop.getFacesUsingVert
 
		radiobuttons rb_detachBy "Detach:" labels:#("verts", "faces") default:1 columns:1
 
		button btn_detachPosX "Detach positive X" width:140
		button btn_detachNegX "Detach negative X" width:140
 
		function DetachVertsByXpos xSide: =
		(
			if selection.count != 0 do
			(
				selObjsArr = selection as array
				for o in selObjsArr where classOf o == Editable_Poly do
				(
					vertsCnt = o.numverts
					posXBA = #{}
					negXBA = #{}
					for v = 1 to vertsCnt do
					(
						vPos = poGetVert o v
						if vPos.x > 0 do posXBA[v] = true
						if vPos.x < 0 do negXBA[v] = true
					)
					case xSide of
					(
						#positive:
						(
							if not posXBA.isEmpty do
							(
								if rb_detachBy.state == 1 then
									poDetachVerts o posXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
								else
								(
									poDetachFaces o (poGetFacesUsingVert o posXBA) delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
								)
							)
						)
 
						#negative:
						(
							if not negXBA.isEmpty do
							(
								if rb_detachBy.state == 1 then
									poDetachVerts o negXBA delete:true asNode:true name:(o.name + "_detachedNegativeX") node:o
								else
								(
									poDetachFaces o (poGetFacesUsingVert o negXBA) delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
								)
							)
						)
					)
				)
			)
		)
 
		on btn_detachposX pressed do
		(
			DetachVertsByXpos xSide:#positive
		)
		on btn_detachNegX pressed do
		(
			DetachVertsByXpos xSide:#negative
		)
	)
	createdialog rol_detachByXpos 
 
)

or if it not works as expected:

(
	global rol_detachByXpos
	try(destroyDialog rol_detachByXpos)catch()
	rollout rol_detachByXpos "Detach by X pos"
	(
		local poDetachFaces = polyop.detachFaces
		local poGetFaceCenter = polyop.getFaceCenter
 
		button btn_detachPosX "Detach positive X" width:140
		button btn_detachNegX "Detach negative X" width:140
 
		function DetachVertsByXpos xSide: =
		(
			if selection.count != 0 do
			(
				selObjsArr = selection as array
				for o in selObjsArr where classOf o == Editable_Poly do
				(
					facesCnt = o.numfaces
					posXBA = #{}
					negXBA = #{}
					for v = 1 to facesCnt do
					(
						fPos = poGetFaceCenter o v
						if fPos.x > 0 do posXBA[v] = true
						if fPos.x < 0 do negXBA[v] = true
					)
					case xSide of
					(
						#positive:
						(
							if not posXBA.isEmpty do
							(
								poDetachFaces o posXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
							)
						)
 
						#negative:
						(
							if not negXBA.isEmpty do
							(
								poDetachFaces o negXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
							)
						)
					)
				)
			)
		)
 
		on btn_detachposX pressed do
		(
			DetachVertsByXpos xSide:#positive
		)
		on btn_detachNegX pressed do
		(
			DetachVertsByXpos xSide:#negative
		)
	)
	createdialog rol_detachByXpos 
 
)
zwrtron's picture

Unfortunately, both don't. :(

Unfortunately, both don't. :(

miauu's picture

.

(
	global rol_sliceOnXaxis
	try(destroyDialog rol_sliceOnXaxis)catch()
	rollout rol_sliceOnXaxis "Slice on X axis"
	(
		local poDetachFaces = polyop.detachFaces
		local poGetFaceCenter = polyop.getFaceCenter
		local poSlice = polyop.slice
 
		button btn_detachPosX "Detach positive X" width:140
		button btn_detachNegX "Detach negative X" width:140
 
		function SliceAndDetach xSide: = with undo "Slice and Detach" on
		(
			if selection.count != 0 do
			(
				selObjsArr = selection as array
				dir = normalize ([100,0,0] - [-100,0,0])
				for o in selObjsArr do
				(
					o.split = on
					poSlice o #all (ray [0,0,0] dir)
					update o
					facesCnt = o.numfaces
					posXBA = #{}
					negXBA = #{}
					for v = 1 to facesCnt do
					(
						fPos = poGetFaceCenter o v
						if fPos.x > 0 do posXBA[v] = true
						if fPos.x < 0 do negXBA[v] = true
					)
					case xSide of
					(
						#positive:
						(
							if not posXBA.isEmpty do
							(
								poDetachFaces o posXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
							)
						)
 
						#negative:
						(
							if not negXBA.isEmpty do
							(
								poDetachFaces o negXBA delete:true asNode:true name:(o.name + "_detachedPositiveX") node:o
							)
						)
					)	
				)
			)
		)
 
		on btn_detachposX pressed do
		(
			SliceAndDetach xSide:#positive
		)
		on btn_detachNegX pressed do
		(
			SliceAndDetach xSide:#negative
		)
	)
	createdialog rol_sliceOnXaxis 
 
)
zwrtron's picture

@miauu - Thank you very much,

@miauu - Thank you very much, exactly what I've been looking for.

jahman's picture

.

you can simply create a copy of your object and apply slice modifier with remove bottom to original and remove top to copy

GIF click if it refuses to play

zwrtron's picture

@jahman - Thank for

@jahman - Thank for contribution, that's the way I've been doing it manually until now.
However, do you think that this approach is more effective than @miauu script? Because using slice works on both editable geometry and primitives where the script only on editable poly.

jahman's picture

.

I personally like slice approach since it isn't destructive.
The only problem to solve here is to align slice plane to world axis properly.

ref = copy $
addModifier $ (SliceModifier Slice_Type:2)
$.modifiers[1].slicePlane.transform = inverse ($.objectTransform * RotateYMatrix 90)
 
addModifier ref (SliceModifier Slice_Type:2)
ref.modifiers[1].slicePlane.transform = inverse (ref.objectTransform * RotateYMatrix 270)

zwrtron's picture

I'll use this method seems to

I'll use this method seems to work on all examples I've tried.
Thank you very much.

Comment viewing options

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