Notifications
Clear all

[Closed] How to find the faces inside an outline ?

Thanks! I tried your method with narrow selections [a few polys], maybe that's the reason?




Light

Here is the break down:

  1. Get current edge selection
  2. Split It [with undo on]
  3. Add new edges to #1
  4. Get face elements of #1 [seperating unconnected elements]
  5. Collect average center of #4
  6. Get average center of #1
  7. Undo
  8. Select face elements whose average center is closes to #6

For #4, you can use Orionflame.getUnconnectedPolys faceList includeCrossPolys thisForm

IE: Orionflame.getUnconnectedPolys faceElements true bitArray

Light

Hi all

I removed the bugs of the script. I think that now it works in every case.
Even if there is only a single polygon!

Thank you for your ideas and specially Stuh: the new script is based at first on your last idea.
Light: effectively the previous version doesn’t work in all case. You were right. In the previous version if an outline selection start from one border of the object to the opposite border, the selection was erroneous. That is corrected.

Now there is no more calculation of centre or distance in the script.
Just bitarray calculations and research of faces.
I have modified the part where I calculate the second selection as the inverse of the first because it does not work in some cases.
It is better.

fn getFirstItem theBitArray = (for i in theBitArray do return i)

fn getContinuousFaces obj outlineEdges firstFace =
	(
	continuousFaces=#{}
	facesToInspect=#{firstFace}
	while facesToInspect.numberset!=0 do (
		currentFace=getFirstItem facesToInspect
		adjacentEdges=polyOp.getEdgesUsingFace obj #{currentFace}
		if (adjacentEdges-outlineEdges).numberset==0 do continuousFaces[currentFace]=true
		for thisEdge in adjacentEdges where ( (outlineEdges*#{thisEdge}).numberset==0 ) do (
			newFace=(polyOp.getFacesUsingEdge obj #{thisEdge})-continuousFaces
			continuousFaces+=newFace
			facesToInspect+=newFace
			)
		facesToInspect[currentFace]=false
		)
	continuousFaces
	)

fn getOutlinesEdges obj theFaces =
	(
	faceEdges=polyOp.getEdgesUsingFace obj theFaces
	openEdges=(for e in faceEdges where (((polyOp.getFacesUsingEdge obj e)*theFaces).numberSet == 1) collect e)as bitarray
	)

fn getOutlineFaces obj outlineEdges =
	(
	theFaces=#{}
	facesToInspect=#{1..polyOp.getNumFaces obj}
	facesGroup=#()
	while facesToInspect.numberset!=0 do (
		currentFaces=getContinuousFaces obj outlineEdges (getFirstItem facesToInspect)
		append facesGroup currentFaces
		facesToInspect-=currentFaces
		)
	openEdgesGroup=for i=1 to facesGroup.count collect (getOutlinesEdges obj facesGroup[i])
	numberOutlineEdges=for i=1 to openEdgesGroup.count collect (openEdgesGroup[i].numberset)
	numberOutlineOpenEdges=for i=1 to openEdgesGroup.count collect ((openEdgesGroup[i]*outlineEdges).numberset)
	if (amax numberOutlineOpenEdges==amin numberOutlineOpenEdges)
		then ( theFaces=facesGroup[findItem numberOutlineEdges (amin numberOutlineEdges)] )
		else ( theFaces=facesGroup[findItem numberOutlineOpenEdges (amax numberOutlineOpenEdges)] )
	theFaces
	)

obj=selection[1]
if classof obj==editable_poly do (
	theFaces=getOutlineFaces obj (polyOp.getEdgeSelection obj)
	polyOp.setFaceSelection obj theFaces
	subObjectLevel=4
	max views redraw
	)

Hey prettyPixel,

Very nice code!

Light

Here is a simplified version of the function getOutlineFaces.
Nevertheless the outline must be without error if not nothing will be selected…

Light, Thanks for the break down of the code

fn getOutlineFaces obj outlineEdges =
	(
	theFaces=#{}
	facesToInspect=#{1..polyOp.getNumFaces obj}
	facesGroup=#()
	while facesToInspect.numberset!=0 do (
		currentFaces=getContinuousFaces obj outlineEdges (getFirstItem facesToInspect)
		append facesGroup currentFaces
		facesToInspect-=currentFaces
		)
	for i=1 to facesGroup.count do ( if ( ((getOutlinesEdges obj facesGroup[i])*outlineEdges).numberset == outlineEdges.numberset ) do theFaces=facesGroup[i] )
	theFaces
	)

prettyPixel: nice solution , when I test this it gives the inverted selection, but it is fast none the less.

Hi Thomas

I’m interested. For the script which I write, I need a function which always gives the right selection. Especially not the inverse selection because this routine will be included in a script which will make several hundreds of selections… And this selections are deleted!
Could you reproduce the error and make a screen shot of your outline please ?
That’s really important for me.

After restarting max this morning I can’t reproduce it on my test scene. If it does it again in a predictable way I’ll share.

Tried a few more configurations and the code seems to be rock solid for me now, I must have had some globals floating around that messed it up before. Way to go prettyPixel.

No problem Thomas.
I think that you created multiple outlines yesterday. The routine supports only a single outline at the same time. Otherwise the result can be unpredictable.

Page 3 / 3