ScriptSpot

Forum topic · General Scripting

Detaching faces and deleting doubled ones if exist

By zwrtron · 2019-07-16

Downloads
Description

I'm looking for a way to programmatically delete certain piece of geometry based on another object or selection. It's hard for me to explain, so please, consider having a following situation.

Consider having complex object, let's say 'Object001' -> a Teapot.

Then cloning the object to -> 'Object002' and attaching the object to back to the 'Object001', so basically, the original 'Object001' will have each face doubled.

Now selecting some faces and detaching them to 'Object003' will result, that there is still one layer of faces present in the area of selection and I want to delete it on detach or explicitly using 'Object003' geometry.

How can I do so using maxscript?

The only solution I think of is to iterate all vertices of 'Object003' and 'Object001' but that's not a good solution for complex geometries. Boolean does not work as excepted.

Please, see the figures in attachments.

Comments (7)

.

miauu · 2019-07-23

Maybe the best aproach is to iterate all faces and to find overlaping faces using the center of the faces. This way you will have less iteration(compared to iterating vertices).

This works with selected polygons. I don't knwo how it will work with complex meshes that you have.


(
	poGetFaceCenter = polyop.getFaceCenter
	poGetFaceSelection = polyop.getFaceSelection
	poDeleteFaces = polyop.deleteFaces
	poDetachFaces = polyop.detachFaces
	
	curO = selection[1]
	
	if classOf curO == Editable_Poly do
	(
		facesNum = polyop.getNumFaces curO
		
		facesIdxArr = #{1..facesNum} as array
		facesCenterPosArr = #()
		for f = 1 to facesNum do
		(
			append facesCenterPosArr (poGetFaceCenter curO f)
		)
		
		selFacesBA = poGetFaceSelection curO
		
		if not selFacesBA.isEmpty do
		(
			overlapFacesArr = #()
			for f in selFacesBA do
			(
				fCPos = facesCenterPosArr[f]
				for p = 1 to facesCenterPosArr.count where facesIdxArr[p] != f and facesCenterPosArr[p] == fCPos do
				(
					append overlapFacesArr facesIdxArr[p]
				)
			)
			
			poDeleteFaces curO overlapFacesArr delIsoVerts:true
			
			poDetachFaces curO (poGetFaceSelection curO) delete:true asNode:true name:"NEW OBJECT"
		)
	)
)

zwrtron · 2019-07-26

Thanks for your answer, but the code deletes the whole geometry not just overlapping faces.

Thanks

zwrtron · 2019-07-26

Oh, yes it actually works exactly as expected, thank you very much. But it's very slow on ~30k + polygons. Is there a way to detach the whole teapot (not just selection) off the object? Just remove all duplicate faces?

.

miauu · 2019-07-27

This code will show you where the slower part of the script is:


(
	gc()
	poGetFaceCenter = polyop.getFaceCenter
	poGetFaceSelection = polyop.getFaceSelection
	poDeleteFaces = polyop.deleteFaces
	poDetachFaces = polyop.detachFaces
 
	curO = selection[1]
 
	if classOf curO == Editable_Poly do
	(
		facesNum = polyop.getNumFaces curO
 
		facesIdxArr = #{1..facesNum} as array
		facesCenterPosArr = #()
		t0 = timestamp()
		for f = 1 to facesNum do
		(
			append facesCenterPosArr (poGetFaceCenter curO f)
		)
		t1 = timestamp()
		format "Time 01: % sec\n" ((t1 - t0)/1000.0)
		selFacesBA = poGetFaceSelection curO
 
		if not selFacesBA.isEmpty do
		(
			overlapFacesArr = #()
			for f in selFacesBA do
			(
				fCPos = facesCenterPosArr[f]
				stopLoop = false
				for p = 1 to facesCenterPosArr.count while stopLoop == false where facesIdxArr[p] != f and facesCenterPosArr[p] == fCPos do
				(
					append overlapFacesArr facesIdxArr[p]
					stopLoop = true
				)
			)
			t2 = timestamp()
			format "Time 02: % sec\n" ((t2 - t0)/1000.0)
			poDeleteFaces curO overlapFacesArr delIsoVerts:true
			t3 = timestamp()
			format "Time 03: % sec\n" ((t3 - t0)/1000.0)
			poDetachFaces curO (poGetFaceSelection curO) delete:true asNode:true name:"NEW OBJECT"
			t4 = timestamp()
			format "Time 04: % sec\n" ((t2 - t0)/1000.0)
		)
		
	)
)

The code works faster then the previous one. Teapot(cloned and attached) with 78400 polys and 342 polys selected - ~56 seconds to find, detach and delete. As you can see the slowest part is where the script tries to find the overlapped faces of the selected faces. So you can try to optimize this part(right now each one of the selected faces are "compared" with all of the other faces).

You can check if the STL modifier can helps you.

chrisell · 2025-04-14

Can I necro this topic? The video showing how it should be used has gone and I'm having the same issue - all the geometry is deleted. It's not clear from reading the maxscript why it's deleting everything.