Get face(poly) by face(mesh) in Maxscript

Get face(poly) by face(mesh) in Maxscript

Anonymous
Not applicable
5,767 Views
9 Replies
Message 1 of 10

Get face(poly) by face(mesh) in Maxscript

Anonymous
Not applicable

Hi there, 

 

I'm having some trouble finding an elegant solution to what IMO should be a simple problem. I'm trying to find what face a face belongs to. The first face being a poly face (polygon), the second being mesh face (triangle). I guess I could lookup which of it's edges is invisible, find that edge in poly and see what polygon uses it, but it seems to me, there must be more straight forward solution to this. Given the fact that some operations returns mesh face even on editable poly, I assume this is a common problem.

 

K.

0 Likes
Accepted solutions (2)
5,768 Views
9 Replies
Replies (9)
Message 2 of 10

Swordslayer
Advisor
Advisor
Accepted solution

Depends, most of the time, you can get the matching poly by the three verts of the face, but there are cases where it will return two different results. If you plan on doing multiple such lookups per one mesh/poly, it's better to make a lookup table to give you the poly index at face index:

 

fn getFacePolyTable obj =
(
	local index = 0
	local polyByFace = #()
	for poly = 1 to polyop.getNumFaces obj do
	(
		local numTris = polyop.getFaceDeg obj poly - 2
		for face = index + 1 to index + numTris do polyByFace[face] = poly
		index += numTris
	)
	return polyByFace
)
Message 3 of 10

Anonymous
Not applicable
Accepted solution

Hi Swordslayer,

 

thanks for the answer. Yeah, getting more than one result is surely a problem. The lookup table should work better, but I've actually found out, that once you convert from mesh to poly it converts the selection. Since I won't be working on highpoly meshes with the tool I'm making, it's a good enough solution for me.

0 Likes
Message 4 of 10

denisT.MaxDoctor
Advisor
Advisor

here is how to get a poly index of poly node by mesh tri index:

 

fn getPolyByTri node tri = 
(
	vv = getface node.mesh tri
	pp0 = #{1..node.numfaces}
	
	for k=1 to 3 do
	(
		pp1 = #{}
		v = vv[k]
		for i=1 to node.getVertexFaceCount v do append pp1 (node.getVertexFace v i)
		pp0 *= pp1
	)
	for p in pp0 do return p
)

there are several ways to optimize the code of course, but it's more to just show the algorithm

 

 

0 Likes
Message 5 of 10

Swordslayer
Advisor
Advisor

@denisT.MaxDoctor That will work most of the time, but not always, for example for the face right to the two selected edges:

 

Screen Shot 2017-11-17 at 19.10.28.png

 

It will report poly 17 which is to the left of it (you can check in the attached scene). And this is a 'proper' quad-only mesh, happens even more often with imported meshes/booleans with large ngons.

0 Likes
Message 6 of 10

Swordslayer
Advisor
Advisor

That can be mitigated by checking if the collected poly numberSet is bigger than one, getting the reverseEdge of the invisible edge, and by that the neighbor face, and intersecting with the neighbor candidate polys. Provided that the degree of the poly in question is bigger than three, that is... If not (very low chance of that, of course), this approach still won't work.

0 Likes
Message 7 of 10

denisT.MaxDoctor
Advisor
Advisor

 


Swordslayer wrote:

@denisT.MaxDoctor That will work most of the time, but not always, for example for the face right to the two selected edges:

 


 

Yes. You right. The code abode is a translation from my c++ code. It was very easy to fix using c++, but for mxs case I need to think a little. 

0 Likes
Message 8 of 10

Swordslayer
Advisor
Advisor

@Anonymous wrote:

 

Yes. You right. The code abode is a translation from my c++ code. It was very easy to fix using c++, but for mxs case I need to think a little. 


Out of curiosity, what does the fixed c++ version look like, if you don't mind sharing?

0 Likes
Message 9 of 10

denisT.MaxDoctor
Advisor
Advisor

# every vertex in MNMesh has list of faces those include this vertex (mesh->vfac)

# MNFace has GetTriangles method which gives a list of corners in triangulation order 

# MNFace has a list of vertices in corners order (f->vtx) and we can make list of mesh vertex indexes 

all that we need is to find a poly that contains sequence of tri vertices in this list..

i'm using std::search

  

 

 

Message 10 of 10

denisT.MaxDoctor
Advisor
Advisor

the fastest mxs function to get poly by tri is slightly modified 

fn getPolyFaceByTri node tri =
(
	local index = 1
	local poly = 0
	local getFaceDeg = polyop.getFaceDeg
	for k = 1 to polyop.getNumFaces node while poly == 0 do
	(
		index += getFaceDeg node k - 2
		if (tri < index) do poly = k
	)
	poly
)