[Closed] Extend Edit_Poly to have Select Face by Area
I have always wanted a modifier like volSelect that selects polygons based on area. It would be important that it update the selection as the topology below it in the stack changes.
I’m doing something wrong with the function. This doesn’t do anything as written but if I create the function outside the plugin first, then the plugin at least prints the face selection… but I still haven’t gotten it to update the actual face selection.
plugin modifier pSelByArea
name:"SelByArea"
classID:#(0x45b71d21, 0x637cf590)
extends:Edit_Poly replaceUI:false version:2
(
fn setFaceSelByArea obj areaVal =
(
local theSelection = #{}
local num_faces = obj.getNumFaces()
for f = 1 to num_faces do
(
local face_Area = obj.GetFaceArea f
if face_Area >= areaVal do append theSelection f
)
print theSelection
return theSelection
)
parameters params_Area rollout:rol_SelByArea
(
spn_MinArea type:#float animateable:true ui:spn_MinArea default:10
on spn_MinArea set val do
(
face_Selection = setFaceSelByArea delegate val
delegate.SetSelection #Face face_selection
delegate.SetEPolySelLevel #Face
)
)
rollout rol_SelByArea "Select By Area"
(
spinner spn_MinArea "Min Area: " range:[0.01,1e9,20]
)
)
I change only this
if face_Area <= areaVal do append theSelection f
and it works
Thanks for testing.
It works for me either way. I think when I tested it before, the object was so small in system units that it the Min Area value was not accurate enough to get subtle selections.
Can (should) I put a callback in the modifier to update if the stack topology changes? My gut tells me it’s a bad idea.
I think using Get handler is a good idea for that purpose
fn setFaceSelByArea obj areaVal =
(
local theSelection = #{}
local num_faces = obj.getNumFaces()
for f = 1 to num_faces do
(
local face_Area = obj.GetFaceArea f
if face_Area <= areaVal do append theSelection f
)
obj.SetSelection #Face theSelection
obj.SetEPolySelLevel #Face
)
...
on spn_MinArea set val do
(
setFaceSelByArea delegate val
)
on spn_MinArea get val do
(
setFaceSelByArea delegate val ; val
)
here is a possible solution but more spec here than me can tell is it fine
plugin modifier polySelByArea
name:"Select By Area"
classID:#(0x45b71d21, 0x637cf590)
extends:Edit_Poly replaceUI:false version:2
(
fn mainCbFn ev nd =
(
local ob = (GetAnimByHandle nd[1])
if isValidNode ob do
(
for m in ob.modifiers where
classOf m == polySelByArea and m.setUpdate do m.minArea
)
)
fn setFaceSelByArea obj areaVal =
(
local theSelection = #{}
local numFaces = obj.getNumFaces()
for f = 1 to numFaces do
(
local face_Area = obj.GetFaceArea f
if face_Area <= areaVal do append theSelection f
)
obj.SetSelection #Face theSelection
obj.SetEPolySelLevel #Face
)
parameters params_Area rollout:rol_SelByArea
(
minArea type:#float animateable:true ui:spn_MinArea default:20
setUpdate type:#boolean ui:chb_SetUpdate default:false
on minArea set val do
(
setFaceSelByArea delegate val
)
on minArea get val do
(
setFaceSelByArea delegate val ; val
)
)
rollout rol_SelByArea "Select By Area"
(
spinner spn_MinArea "Min Area: " range:[0.01,1e9,20]
checkbox chb_SetUpdate "Auto Update"
)
on create do
(
NodeEventCallback geometryChanged:mainCbFn topologyChanged:mainCbFn
)
on postLoad do
(
NodeEventCallback geometryChanged:mainCbFn topologyChanged:mainCbFn
)
)
EDIT* … woops, little correction needs for creating the callback only once in ‘on create’ and ‘on postLoad’:
if ::cbUpdateModSelByArea == undefined do
cbUpdateModSelByArea = NodeEventCallback geometryChanged:mainCbFn topologyChanged:mainCbFn
That’s better. It acts a little funny but it is decent. Thanks for the additions.