View Full Version : Weld vertices in multiple splines at once
01-22-2008, 01:42 PM
I have a file with lots of splines (hundreds) to which I need to apply weld command as many vertices are not connected.
So I'm trying to automate that through a script. I found on the forum a base code to do that and tried to wrap it into a loop to cycle through all the splines in my selection :
for s in selection do
max select all
The problem is that it does not cycle through all the splines but only performs the operation on one and stops.
I think the problem might be that once I enter in subobjectlevel I should exit it no ?
Any help is welcome of course.
01-22-2008, 09:53 PM
Look at the code. You want to cycle through the selection set. Then the first thing you say is: select s. So now you've replaced the selection set with just the first object in the selection. So it makes sense that it only works on the first object. After the first time through the loop, it's the only thing selected and the loop ends.
You need to create a copy of the selection set before you start manipulating it. Something like:
for s in selection as array do
max select all
subobjectLevel=0 -- you need this, otherwise everything stays at 1
Now s steps through the selection set as it was at the start, ignoring the changes you make. Also note that you should close the subobject level.
01-22-2008, 10:14 PM
focomoso is correct (as I'm sure he knew he was), it is good practice to first make a "snapshot" of any of max's collection sets (objects, geometry, lights, cameras, helpers, systems, spacewarps and selection) before you try and do any work against them. This allows you to work on the result in isolation without been adversly affected by changes to the original objectset.
01-23-2008, 08:48 AM
Thanks a lot for your help focomoso.
With your suggestion, the script seems to do what it should as it runs for a few seconds while it used to run instantaneously with my lame version.
But the problem is that when it finishes I end up with only the last shape of the set being welded.
I tried to run it on a very simple test scene with only 5 rectangles with one corner vertex broken and it doesn't work neither, well it works on the last one only.
01-23-2008, 10:58 AM
Things may have changed since I last tried something like this a few years ago, but at the time there was a problem with welding spline verts in a loop, it simply didn't work and was apparently a limitation of the ancient spline code.
01-23-2008, 11:59 AM
a problem with welding spline verts in a loop, it simply didn't work and was apparently a limitation of the ancient spline code.
Really !? . So I am not lucky at all : I almost never do any scripting (and you might have guessed that throgh my poor code hehe) and now that I want to script something it happens to be precisely a thing that does not work because of a limitation :shrug:
01-23-2008, 01:02 PM
I tried this for max8 and haven't looked at it since, but a few pointers:
The AVG Extension has a better spline weld routine that lets you specify a threshold.
Prior to max9 more than a few thousand verts selected and welded really slows everything down so try to reduce the count before doing the weld - I went through the splines and only selected the end verts (the middle ones don't need welding) on open splines (exclude ones that are closed as they can't weld to anything anyway).
I also at the time did a count routine that split the operation into batches of 500 verts so that I could see if max had crashed or was just being really slow.
hope that helps
The problem is in the splineOps. The function only works if the object is selected and the modify panel is on the right modifier. So in the loop you would need to call a redraw for it to work. But from what I know maxscript doesn't let you do a complete redraw or something... looks like splineOps is too slow too catch up with max for loops or something.. don't know why exactly it doesn't work... But I have a workaround:
fn splineWeld =
o = objs
if o == undefined then
) else (
modpanel.setCurrentObject o.baseObject ui:true
subobjectLevel = 1
max select all
subobjectLevel = 0
deleteItem objs 1
objs = for o in selection where iskindof o line collect o
/* WORKS */
theTimer = dotNetObject "System.Windows.Forms.Timer"
dotnet.addEventHandler theTimer "tick" SplineWeld
theTimer.interval = 100
/* DOESN'T WORK */
--for o in objs do splineWeld()
Basicly it's an dotnet Timer function which calls the weld function. This seems to update max innerworkings as I think the "dotnet scope" is not the same as the maxscript scope.. somehow this way updates max the right way making it accept the splineOps function...
Anyone who can explain better please do!
Probably the code can be made better too... feel free!
Or you could do what Alex said:
for o in selection where iskindof o line do weldSpline o 0.1
Where 0.1 is the treshold... weldspline is default in max2008, previous version you would have to get the AVG extension from maxplugins.
:) Thanx Alex.. ohwell, still the timer function could be usefull for other Ops structs...
01-24-2008, 09:28 AM
Thanks a lot JHN for taking the time to write down that wonderful script though I must admit I didn't understand neither the problem neither the solution you brought to it :)
Anyways, I first tried the script on my test file with just a few simple splines and it worked like a charm, cycling through all the shapes and welding them. But when I tried to run it on my project it just does nothing, and there is no error message. Very strange.
But it's ok. The deadline is approaching and I have to finish that thing. So I just assigned the part of script that welds a spline to a hotkey and then welded them all one by one. It took me about 20mn :rolleyes:
I'll look deeper into this as soon as I have a little time because I'm sure I'll have to face such situation again in future projects.
Again, thanks to all of you for your kind help.
Maybe the imported splines are of an different class then "line".
You can check if you select 1 object and type in the listener
And (numeric) enter... my code filters only on line, but if the class is different it won't do a thing... I'm thinking that's what happened... replacing line with the class you get will probably work.
01-24-2008, 11:02 AM
Yes you're right. I changed that to SplineShape and it worked ok !
01-24-2008, 11:18 PM
Basicly it's an dotnet Timer function which calls the weld function.
Hi I use max 8 at the office and your code with dotnet does not work in my computer. I spend the whole day trying to figure this "welding" issue without success within a loop. How could I activate or what should I install to be able to run this dotnet Timer function in my office's PC? Would you please help me?
Unfortunatly the dotNet solution will not work in max8, because it's first implementation was in max 9....
Maybe you'll have more luck with the timer control for rollouts. But it will require you to make a rollout... don't know of any other way to use timers in max.. maybe soneone else..?
If you want to weld in max8, use the second small script and install the AVGaurd extension form maxplugins.
01-25-2008, 09:23 AM
It worked!!! Amazing man, you're the best!!! Thanks a lot!
01-25-2008, 09:23 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.