[Closed] Looking for unusual scale tool
Hello everyone,
Even though it’s my first post here, I’m not for the first time on this board for sure
I’ll be straight to the point. I’ve got a problem which I haven’t been able to resolve yet, and I was wondering if what I’m after is even possible.
Let’s say I have a mesh, a road, and that road has a 90 or any other degree turn. Now there are several types of “scaling” tools but all of them do not do what I need them to do. Take a look at this image:
I was wondering if there’s any way I can scale this object (larger/smaller) the way that the red (selected) vertices move along horizontal line which connects a pair of parallel vertices, just like the green arrows show. That also means that the centerline must not move, i.e. the whole object must not shift anywhere, only the outside vertices must move along the line which connects these vertices. So in other words, each vertex must move in relation to its corresponding vertex. In my example, for instance, if I were to make this mesh larger with this non-existent tool, the inside vertices/lines would intersect eventually, and the outer vertices would spread out more.
Is there anything in/for 3dsmax which is able to do this? Or if not, is it possible to write a script which would do such job depending on what vertices are selected? If yes, how hard would it be?
Thanks for any information you can give,
Oleg
I just wrote a script for you to do that.
It does not scale, it OFFSETS the selected vertices based on absolute distance. Works great, but I want to make some adjustments before I post it…
Cheers,
Bobo
Probably very similar to Light’s Push (haven’t tried that)…
macroScript OffsetVertsByEdge category:"Bobo's Polytools"
(
global OffsetVertsByEdges
on isEnabled return selection.count == 1 and subObjectLevel == 1 and classof selection[1] == Editable_Poly
on execute do
(
theObj = selection[1]
thePairsArray = #()
theVerts = polyOp.getVertSelection theObj
for v in theVerts do
(
theEdges = polyOp.getEdgesUsingVert theObj v
theEdgesToUse = for edge in theEdges where ((polyOp.getFacesUsingEdge theObj edge) as array).count == 2 collect edge
if theEdgesToUse.count > 0 then
(
theFullVector = [0,0,0]
for edge in theEdgesToUse do
(
theEdgeVerts = (polyOp.getVertsUsingEdge theObj edge) as array
deleteItem theEdgeVerts (findItem theEdgeVerts v)
theFullVector += normalize ((polyOp.getVert theObj theEdgeVerts[1]) - (polyOp.getVert theObj v))
)
append thePairsArray #(v, polyOp.getVert theObj v, theFullVector )
)
)--end v loop
try(destroyDialog OffsetVertsByEdges)catch()
rollout OffsetVertsByEdges "ScaleVertsByEdges"
(
spinner spn_scale "Offset:" range:[-100000.0,100000.0,0] fieldwidth:70 type:#worldunits
on spn_scale changed val do
for i in thePairsArray where length i[3] > 0.0 do
polyOp.setVert $ i[1] (i[2] + (normalize i[3])*val)
)
createDialog OffsetVertsByEdges
)--end on execute
)--end script
NOTE: You should hide the diagonal edges and convert to Editable Poly because my script (and probably Light’s) uses the visible edges as vectors to push along. If you keep the edges perpendicular to the road (and the central edges along the path) and hide all diagonals, the vertices should move along the arrows you described in your first post…
Exactly Bobo
One thing I wonder: your script doesn’t create an undo when I am adjusting the value multiple times [which is good], is it intentional? But it also doesn’t create an undo after I close the dialog. I think one should manually add an undo record in dialog’s close event handler, right?
Light
Sort of intentional.
Because the script records the original positions of all vertices in an array along with the indices and vectors, setting the spinner back to 0.0 is equal to UNDO. I would rather not deal with theHold and tracking spinner activities…
[left]Hi guys, thank you very much for the quick responses and already with some solutions, I couldn’t even ask for more! I haven’t tried the Light’s push yet, but I’ve been trying to make the Bobo’s script work, and unfortunately I’m getting some errors from the compiler:[/left]
[left]
[/left]
[left]
[/left]
[left]– Compile error: No outer local variable references permitted here: thePairsArray[/left]
[left]– In line: for i in thePairsArray where length i[3] > 0.0 do[/left]
[left]
[/left]
[left] [/left]
[left]Any ideas?[/left]
There are one line of code to add.
global thePairsArray=#()
after the line
global OffsetVertsByEdges
I tested it. I like this tool
Thanks prettyPixel! I’ve got it to work finally
Bobo, works great (!), really, exactly how I wanted the object to be “scaled”, there’s just one problem, the whole mesh is with those tris, i.e. diagonal edges, of course I can remove them manually, but the mesh is really huge will take quite awhile to remove them all. Is there any simple way of getting rid of the diagonal edges? Or can they be ignored by the script?
Oleg,
Try using Quadrangulate. Although this has a pretty basic logic, it might work if the topology is uniform by means of indices.
Light