View Full Version : Invert current face selection
reForm 11-01-2006, 03:45 PM This is probably a really simple function to achieve, but how do invert the current face selection in an editable poly object?
Is there a maxscript command that does this, or do I need to build an array of the non-selected faces, then select the contents of that array?
|
|
This is probably a really simple function to achieve, but how do invert the current face selection in an editable poly object?
Is there a maxscript command that does this, or do I need to build an array of the non-selected faces, then select the contents of that array?
Selections are returned as bitarrays. Bitarrays are arrays where each element is just true or false. As you can see from the MAXScript Reference, inverting a bitarray is as easy as taking the existing bitarray with negative sign!
So you would first get the current selection and then set the same selection with negative sign:
theSel = polyOp.getFaceSelection theObject --get selection
polyOp.setFaceSelection theObject -theSel --set selection
redrawViews() --refresh viewports
or shorter,
polyOp.setFaceSelection theObject -(polyOp.getFaceSelection theObject)
redrawViews()
reForm
11-01-2006, 04:21 PM
Wow that was fast. Thanks Bobo!
I assume polyOp commands can only work on editable_polys and not e.polys with editable polygon modifiers in the stack? (ie on the top level of the stack)
I'm struggling to delete the selected faces.
Thanks again for you help.
Wow that was fast. Thanks Bobo!
I assume polyOp commands can only work on editable_polys and not e.polys with editable polygon modifiers in the stack? (ie on the top level of the stack)
I'm struggling to delete the selected faces.
Thanks again for you help.
The syntax for Edit_Poly is slightly different.
You would have to figure out whether your currently selected object in the modifier stack is Editable_Poly, Edit_Poly or Editable_Mesh and use the correct code based on that.
For Edit_Poly, the syntax is
theObject.setSelection #Face -(theObject.getSelection #Face)
Here is how to check the current selection in the modifier stack:
theObject = modPanel.GetCurrentObject()
case classof theObject of
(
Editable_Poly: ( ) --put the PolyOp version here
Edit_Poly: ( ) --put the Edit_Poly version here
)
Here is a slightly extended function:
fn InvertFaceSelection =
(
theObject = modPanel.GetCurrentObject()
if theObject != undefined and subObjectLevel > 2 do
(
case classof theObject of
(
Editable_Poly: ( polyOp.setFaceSelection theObject -(polyOp.getFaceSelection theObject) )
Edit_Poly: ( theObject.setSelection #Face -(theObject.getSelection #Face) )
Editable_Mesh: ( setFaceSelection selection[1] -(getFaceSelection selection[1]) )
Mesh_Select: ( setFaceSelection selection[1] theObject -(getFaceSelection selection[1] theObject) )
Edit_Mesh: ( setFaceSelection selection[1] theObject -(getFaceSelection selection[1] theObject) )
)
redrawViews()
)
)
InvertFaceSelection()
reForm
11-01-2006, 05:20 PM
You must be having a quiet day today!
Looking at the example you used for the case where the object has an edit_poly modfier, I wanted to test this using an object in the scene, with the listener... so I replaced 'the_object' with $ ie
$.setSelection #Face -($.getSelection #Face)
This should invert the selection as you say, but it appears to do nothing. What am I doing wrong?
To give this discussion some context, I'm writing a script that does the following :-
make a reference copy of the selected mesh (which will always be a editable_poly).
add an editable poly modifier
select all faces
inset by a specified distance
delete selected faces (the inset typically leaves the new polygons unselected)
add shell modifier
So the caseof code isn't strictly necessary (although I do need some kind of error checking).
The reason I want to do this without collapsing the mesh(which I assume would allow me to use polyops and would be easier to code) is so that the base mesh remains the 'cage' that controls the result of the script, ie I can change the shape of the new (script)object based on the base object.
Thanks again for your input Bobo!
reForm
11-01-2006, 05:25 PM
Ah, I managed to get it working:-
$.modifiers[#Edit_Poly].setSelection #face -($.modifiers[#Edit_Poly].getSelection #face)
Is there a cleaner way to access the modifier in the stack for this kind of operation?
reForm
11-01-2006, 05:29 PM
Also, how do I delete the selected faces?
reForm
11-01-2006, 05:49 PM
Hmm, well it works in the listener
$.modifiers[#Edit_Poly].setSelection #face (-($.modifiers[#Edit_Poly].getSelection #face))
but if I put it into the script I get an error
--No ""u-"" function for undefined
obj_glass.modifiers[#Edit_Poly].setSelection #face (-(obj_glass.modifiers[#Edit_Poly].getSelection #face))
You must be having a quiet day today!
Looking at the example you used for the case where the object has an edit_poly modfier, I wanted to test this using an object in the scene, with the listener... so I replaced 'the_object' with $ ie
$.setSelection #Face -($.getSelection #Face)
This should invert the selection as you say, but it appears to do nothing. What am I doing wrong?
You are using $ which is the current selection.
My example takes the actual modifier displayed on the stack regardless of what object is selected and works with it. -- see modPanel.getCurrentObject(). This returns the currently selected level of the modifier stack. I used $ or selection[1] for the EMesh stuff though as those methods work on the node instead.
Hmm, well it works in the listener
$.modifiers[#Edit_Poly].setSelection #face (-($.modifiers[#Edit_Poly].getSelection #face))
but if I put it into the script I get an error
obj_glass.modifiers[#Edit_Poly].setSelection #face (-(obj_glass.modifiers[#Edit_Poly].getSelection #face))
This is because the method only works if the Edit_Poly is selected in the modifier stack.
This is why I am using modPanel.getCurrentObject() - I want to make sure the modifier is actually selected in the stack before I operate on it.
If the modifier is not active on the stack, the getSelection() method returns undefined, and the error message says you cannot take a negative of undefined.
Your approach has another caveat - if you have two Edit_Poly modifiers with the same name, your script will always modify just one of them.
If your script has to operate without user interaction (like setting the right selection on the stack), you will have to make sure your script does the job - make the modifier stack active, detect the top-most Edit_Poly on the stack and set the current object on the stack to that modifier before you call the code.
To delete using Edit_Poly, use theMod.buttonOp #deleteFace
(
max modify mode --switch to modify panel
theNode = selection[1] --get selected object
for m in theNode.modifiers where classof m == Edit_Poly do --find Edit_Poly modifier
(modPanel.setCurrentObject m; exit) --set as current object on the stack
modpanel.getCurrentObject() --grab the current object from the stack
--optionally invert the selection here...
theObject.ButtonOp #deleteFace --push the delete faces button
)
reForm
11-01-2006, 06:24 PM
Thanks again, that makes things alot clearer.
I'll let you know how I get on.
:thumbsup:
reForm
11-01-2006, 10:05 PM
I got it sorted in the end. I couldn't have done it without ya.
Thanks again.
CGTalk Moderation
11-01-2006, 10:05 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.