So you want to make a Select Face By Area modifier in MCG…. here’s a quick guide.
You want two things to start with for making any modifier which modulates your existing mesh… a Modifier:TriMesh as your input and an Output: Modifier as your output Node.
Save this as “SelectFaceByArea.maxtool” in the Tools folder of MCG. You can Run this (Ctrl+E) and you’ll find it in your modifier stack and if you apply it, it will just return your original mesh.
Searching for *FaceSelection we find the “SetFaceSelection” Node, when we look at the Description for this node it says:
Signature: (TriMesh, IArray[Boolean]) -> TriMesh
So this means the node wants a TriMesh Input and will give us a TriMesh Output which we can see from the colour coding of the sockets so we can straight away plug this in between our input and output nodes. But what about this faceSelection(IArray) third socket…. Well looking at the description it says IArray[Boolean] so it wants an array of booleans to tell it which faces it wants to select. So our array must be the same size as the number of faces in the mesh.
When we look we for a node which might take our mesh and get the faces we find two, MeshFace and MeshFaces, one gives us just the one specified face and the other gives us all the faces. Using the MeshFaces node we get an IArray of faces as an output. We can plug this into our Modifier: Trimesh Node as a second connection. Looking at the description of the MeshFaces Node we see the Signature says (TriMesh) -> IArray[Face3] So it’s going to make an array of Face3 Values. You’ll find a FaceArea Node which has an input of “Face (face3)” so we can now say we want to loop over all our face3 values in the array. Now when you look for a loop node in MCG you will be dissapointed.. there isn’t one… this seems really strange at first but once you’re used to it, you’ll see why. What we want here is a ‘Map’ node… that takes an IArray and outputs an IArray and it performs a function on each item in the array.
The fxn(Func) input is where we want to define what our function is… So what is our function? We want to go test every face against a value to see if it’s Less than it. So we are starting with a size, comparing it against a size, and returning a true/false value. Which is good as we want to start with an IArray of face3 values and end up with an IArray of Boolean (true/false) values. Our faceArea node outputs a ‘Single’ value, which is basically a float.. we want to test it against another single value so we could either define the value within MGG or we could make it a Parameter so the user can play with the value… so let’s do that. Create a Parameter:Single and then join both of these up with a LessThanOrEqual Node… which should hopefully make sense. The LessThanOrEqual node can have ‘Any’ inputs or outputs, but your inputs should match in type.. you can’t compare Integers and Singles as it doesn’t do type conversion for you, so you may need in another case to use a ‘asFloat’ node as well.
So that’s our function in isolation. Now take the Function(fxn) output of the LessThanOrEqual node and connect it into the fxn(Func) input socket of the Map node. You’ll notice of course that the face3 socket of the FaceArea node doesn’t have anything in it. This is where MCG’s user experience is a bit tricky to get at first. The Map node throws out each item in the IArray and it’s actually clever enough to know where the argument is supposed to go. With the socket open it knows this is where to throw the array item to. So we’ve now got a function which tests our parameter against the face area.
One last annoying user experience quirk. If you Save and Run this (Ctrl+E) it won’t look like it’s working, but actually it is… MCG can’t invoke the sub-selection mode in the modifier stack. So if you put a PolySelect modifier below yours and set it to Face mode, now your tool will work.