Detaching faces and deleting doubled ones if exist

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.

AttachmentSize
fig1.png118.11 KB
fig2.png28 KB
fig3.png109.55 KB

Comments

Comment viewing options

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

.

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's picture

Thanks for your answer, but

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

miauu's picture

.

Please, watch this video:

https://drive.google.com/open?id=1t-YyxRo8bRpMxswz2z_xF_mi-QzuGuzj

The script works with selected polygons and deletes the selected polygons.

zwrtron's picture

Thanks

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's picture

.

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.

Comment viewing options

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