Dave Black
11-09-2005, 07:37 PM
Ok, so this script actually works, but with some unacceptable problems. In the case of the supplied code, it matches the Y pos of a selection of verts to the Y axis of a single picked vert. Think of it like a vertex-level align tool. Which rocks. Bobo has helped me with the general implementation, particularly with not having to use the "pickPoint" function. Thank you Bobo.
The problem is, I cannot figure out a way to get it to stop looking for the second selection if the user wants to cancel the operation, or does not pick a vertex. It just keeps looking for a vertex selection until the user does so. This could be very annoying. And is.
The problem originates from the code's sneaky workaround. When the vertex selection changes, one of two things can happen. First, if no vertex is selected, it will return a #{} using the polyop.getVertSelection function. However, if a vertex is selected after a vert is highlighted, max actually deselects the first vert, and then selects the one picked. This sends two callbacks for a vert selection. One of #{} and then one of #{vertnumber}. So it basically always returns an empty array for every pick, and screws up the if expression.
It's not possible to use the select change handler with the "handleAt:#redrawViews" parameter. The problem with using this parameter, is that since the script runs when the selection changes and therefore when the viewports are refreshed, the viewport does not refresh once the verts are moved. This means that it requires an additional click for the viewport to update after the script runs. This is obviously not acceptable.
So I have two options. Either the user has to live with having to pick a vertex before the operation completes(thus possibly leaving a handler running), or they have to manually refresh the views, as none of the refresh views code works within the when handler, or perhaps it does, but it gets caught in a loop somehow.
Since the system always follows the same pattern, ie. on selecting a new vert, it returns: unselected, selected.
and then when no vert is selected(like you pick outside the mesh and it clears the selection) it returns a simple unselected.
Using this pattern, I thought I could construct a second set of code the monitors for these patterns, and then compares them to figure out when to exit. I have not been able to get this to work.
I am stupid, and cannot figure out any way around this.
Help me, CGTalk, You're my only hope. Sorry for the complex question, but it's a complex issue.
(
deleteAllChangeHandlers id:#monitorVerts
if selection.count == 1 and classof $ == Editable_Poly and subObjectLevel == 1 do
(
DMB_InitialVerts = (polyop.getVertSelection $)
DMB_InitialVerts_Array = (polyop.getVertSelection $) as array
if DMB_InitialVerts_Array.count != 0 then
(
when select $ change id:#monitorVerts do
try
(
if selection.count == 1 and classof $ == Editable_Poly and subObjectLevel == 1 do
(
DMB_TargetVert = (polyop.getVertSelection) selection[1] as array
if DMB_TargetVert.count == 1 do
(
DMB_TargetVertPos = polyop.getVert selection[1] DMB_TargetVert[1]
deleteAllChangeHandlers id:#monitorVerts
for i in 1 to DMB_InitialVerts_Array.count do
(
DMB_TempVertPos = polyop.getVert selection[1] DMB_InitialVerts_Array[i]
polyop.setVert $ DMB_InitialVerts_Array[i] [DMB_TempVertPos[1], DMB_TargetVertPos[2], DMB_TempVertPos[3]]
)
)
)
)
catch()
)
else
(
messagebox "Please select at least one vertex"
)
)
)
-Dave
The problem is, I cannot figure out a way to get it to stop looking for the second selection if the user wants to cancel the operation, or does not pick a vertex. It just keeps looking for a vertex selection until the user does so. This could be very annoying. And is.
The problem originates from the code's sneaky workaround. When the vertex selection changes, one of two things can happen. First, if no vertex is selected, it will return a #{} using the polyop.getVertSelection function. However, if a vertex is selected after a vert is highlighted, max actually deselects the first vert, and then selects the one picked. This sends two callbacks for a vert selection. One of #{} and then one of #{vertnumber}. So it basically always returns an empty array for every pick, and screws up the if expression.
It's not possible to use the select change handler with the "handleAt:#redrawViews" parameter. The problem with using this parameter, is that since the script runs when the selection changes and therefore when the viewports are refreshed, the viewport does not refresh once the verts are moved. This means that it requires an additional click for the viewport to update after the script runs. This is obviously not acceptable.
So I have two options. Either the user has to live with having to pick a vertex before the operation completes(thus possibly leaving a handler running), or they have to manually refresh the views, as none of the refresh views code works within the when handler, or perhaps it does, but it gets caught in a loop somehow.
Since the system always follows the same pattern, ie. on selecting a new vert, it returns: unselected, selected.
and then when no vert is selected(like you pick outside the mesh and it clears the selection) it returns a simple unselected.
Using this pattern, I thought I could construct a second set of code the monitors for these patterns, and then compares them to figure out when to exit. I have not been able to get this to work.
I am stupid, and cannot figure out any way around this.
Help me, CGTalk, You're my only hope. Sorry for the complex question, but it's a complex issue.
(
deleteAllChangeHandlers id:#monitorVerts
if selection.count == 1 and classof $ == Editable_Poly and subObjectLevel == 1 do
(
DMB_InitialVerts = (polyop.getVertSelection $)
DMB_InitialVerts_Array = (polyop.getVertSelection $) as array
if DMB_InitialVerts_Array.count != 0 then
(
when select $ change id:#monitorVerts do
try
(
if selection.count == 1 and classof $ == Editable_Poly and subObjectLevel == 1 do
(
DMB_TargetVert = (polyop.getVertSelection) selection[1] as array
if DMB_TargetVert.count == 1 do
(
DMB_TargetVertPos = polyop.getVert selection[1] DMB_TargetVert[1]
deleteAllChangeHandlers id:#monitorVerts
for i in 1 to DMB_InitialVerts_Array.count do
(
DMB_TempVertPos = polyop.getVert selection[1] DMB_InitialVerts_Array[i]
polyop.setVert $ DMB_InitialVerts_Array[i] [DMB_TempVertPos[1], DMB_TargetVertPos[2], DMB_TempVertPos[3]]
)
)
)
)
catch()
)
else
(
messagebox "Please select at least one vertex"
)
)
)
-Dave
