PDA

View Full Version : Looking for unusual scale tool


Xatrix
09-18-2005, 10:12 PM
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:

http://img129.imageshack.us/img129/4288/newmesh8cg.jpg

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

Light
09-19-2005, 12:07 AM
Oleg,

Although you have intermediate edges between those vertices, try using Push (http://www.orionflame.com).




Light

Bobo
09-19-2005, 12:48 AM
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

Bobo
09-19-2005, 01:00 AM
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

Bobo
09-19-2005, 01:24 AM
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...

Light
09-19-2005, 01:52 AM
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

Bobo
09-19-2005, 03:22 AM
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... ;)

Light
09-19-2005, 03:47 AM
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... ;)

That's reasonable :thumbsup:



Thanks,
Light

Xatrix
09-19-2005, 11:52 AM
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:



-- Compile error: No outer local variable references permitted here: thePairsArray
-- In line: for i in thePairsArray where length i[3] > 0.0 do


Any ideas?

prettyPixel
09-19-2005, 09:40 PM
There are one line of code to add.

global thePairsArray=#()

after the line
global OffsetVertsByEdges

I tested it. I like this tool :thumbsup:

Xatrix
09-20-2005, 08:30 AM
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?

Light
09-20-2005, 09:23 AM
Oleg,

Try using Quadrangulate (http://www.orionflame.com). Although this has a pretty basic logic, it might work if the topology is uniform by means of indices.




Light

Xatrix
09-20-2005, 10:47 AM
Light,

thank you. That's basically what I was hoping for, but I guess the topology isn't correct or something, here's what mesh I get after the script:

http://img365.imageshack.us/img365/4654/quadrangulate5ni.jpg

there's not much I can do about it right? Although it does work if I select just two tris, sometimes more than 2 and it still works ok, but that's an exception rather than a rule, it always comes out like it's shown in the pic.

Neithertheless, that's already something! I thank you all for the help, if you have any other suggestions I'd really appreciate that.

Oleg

Light
09-20-2005, 10:52 AM
OK, try this:

Open Pola X > Length and select a diagonal edge you want to remove and press "?" and "=". This should select all diagonal edges that are equal in size to the first one you have selected.




Light

Xatrix
09-20-2005, 11:47 AM
Okay! That's already better, though few edges were selected that way, so I've chosen to select by range (from-to) and that worked better :) Thanks for that!

Light
09-20-2005, 02:02 PM
Glad it worked for you! You can also do that by selecting 2 edges and pressing "@" which would define a range on the fly.




Light

prettyPixel
09-20-2005, 04:06 PM
In a case like that one, it would not be easier to modify original script ? ...

Instead of to calculate the vector the vector based on the edge which contains 2 faces, it would be more interesting to calculate the perpendicular of the 2 open edges (in face plane)

I am not familiar with this kind of calculation but I am sure that it is easy for a good programmer.

Xatrix
09-20-2005, 08:05 PM
you got me interested again :D
yea, the more I use the scripts the more I understand how powerful they are, pretty much anything can be done, even such unusual task, but then again, I'm good at setting unusual tasks :D Too bad I'm not a Max scripter nor am I a good modeler... but am a programmer :rolleyes: Without knowing 3dsmax inside out, my programming skills do not help me write scripts for 3dsmax, cause that's just completely different...

prettyPixel
09-21-2005, 01:21 AM
Here is a modified version of bobo script.
His name is OffsetVertsByEdge2 and you will find it in the same category (Bobo's Polytools).
I hope it does what you wish.
That seems correct.

macroScript OffsetVertsByEdge2 category:"Bobo's Polytools"
(
global OffsetVertsByEdges2
global thePairsArray=#()
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 == 1 collect edge
theOtherEdgesToUse = for edge in theEdges where ((polyOp.getFacesUsingEdge theObj edge) as array).count == 2 collect edge
if theOtherEdgesToUse.count > 0 then
(
theFullVector = [0,0,0]
for edge in theEdgesToUse do
(
v1a=polyOp.getVert theObj v
theVerts=(polyOp.getVertsUsingEdge theObj edge)as array
if theVerts[1]==v then v1b=polyOp.getVert theObj theVerts[2] else v1b=polyOp.getVert theObj theVerts[1]
v1=v1b-v1a
theVerts=(polyOp.getVertsUsingEdge theObj theOtherEdgesToUse[1])as array
if theVerts[1]==v then v2b=polyOp.getVert theObj theVerts[2] else v2b=polyOp.getVert theObj theVerts[1]
v2=v2b-v1a
theFullVector+=normalize (cross v1 (cross v1 v2))
)
append thePairsArray #(v, polyOp.getVert theObj v, theFullVector )
)
)--end v loop

try(destroyDialog OffsetVertsByEdges2)catch()
rollout OffsetVertsByEdges2 "ScaleVertsByEdges2"
(
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 OffsetVertsByEdges2
)--end on execute


)--end script

Hope this helps ;)

Xatrix
09-21-2005, 08:46 AM
wow!! amazing stuff :eek:
Thank you, prettyPixel! That's 100% what I needed!
:bowdown: :bowdown: :bowdown:

Thank you all guys for the help, long live CGTalk and its members
:wavey:

Oleg

CGTalk Moderation
09-21-2005, 08:46 AM
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.