How To > Flatten a SplineShape |
The following tutorial shows how to access and modify the splines and their knots (vertices) and tangents in a SplineShape. The resulting macroScript will move all knots to the Z height defined by the shape’s Z position, thus aligning them to a plane parallel to the ground XY world construction plane.
Spline Shape Common Properties, Operators, and Methods
The macroScript will be called FlattenSpline . To use the script, you can go to Customize... and drag the script from the category "HowTo" to a toolbar, a menu, a quad menu or assign to a keyboard shortcut.
on isEnabled return ( selection.count == 1 and \ (classof selection[1] == SplineShape or \ classof selection[1] == Line) \ and selection[1].modifiers.count == 0 )
The macroScript ActionItem (button, menu item, shortcut) will only be enabled when the scene selection contains a single object AND this one object is either a SplineShape class (in other words an EditableSpline) without any modifiers as MAXScript cannot modify a spline with modifiers on top. The result of the expression after the return statement evaluates to true or false. When true, the script becomes enabled.
In these lines we compare the count of the current scene selection with 1, then the class of the first selected object to the class SplineShape. Then once again we compare the class of the first selected object with the class Line as a newly drawn line would be an exception – we can modify it, but the class is not SplineShape until collapsed to EditableSpline. Lastly, we check the number of modifiers and compare to 0.
If the first AND either the second OR the third, AND the fourth condition are true, the selected object is valid and can be modified by the script!
Macroscript_Body_Event_Handlers
The on execute handler contains the actual code. It will be executed whenever the script is started by clicking the button, selecting the item from a menu, using the keyboard shortcut etc.
Macroscript_Body_Event_Handlers
We will need the Z coordinate of the splineShape in order to move all Knots and Tangents to that position. We store the Z component of the position of the scene selection in the user variable new_z. Because we already checked in the isEnabled handler that there is only one object selected, we don’t need to use selected[1] to access the first selected object – we are completely sure the $ representing the current selection is actually a single object!
A splineShape can contain any number of splines (a Donut shape for example contains two circles!). To change every single spline, we will create a for loop which counts from 1 to the number of splines in the selected object.
Each spline in the shape can contain any number of knots. To change every single knot, we will create another for loop which counts from 1 to the number of knots in the s-th spline – the index of the spline is controlled by the outer for loop. Note that the for k... loop will be executed again and again for each repetition of the for s loop. So these are nested loops!
Using getKnotPoint, we read the K-th knot in the S-th spline in the selected splineShape. We store its Point3 world coordinates in the user variable knt.
Then we read the in vector of the K-th knot in the S-th spline in the selected splineShape. We store its Point3 world coordinates in the user variable in_vec.
We read the out vector of the K-th knot in the S-th spline in the selected splineShape. We store its Point3 world coordinates in the user variable out_vec.
Now we can set the Z coordinate of both vectors and the knot to the new value stored in the new_z variable. Note we can assign the same value to multiple variables as MAXScript processes the expression by evaluating the right-hand side of the assignment first then assigning the result to the left-hand side and so on.
Now we can assign the new in and out vectors back to the respective knot and spline.
Then we assign the new knot position back to the respective knot and spline.
Finally, it is very important to update the splineShape. This makes all changes visible by updating the internal data structures. Failing to do so could cause instabilities in 3ds Max.
Evaluate the script. To use it, you can use Customize... to drag the script from the category "HowTo" to a toolbar, a menu, a quad menu or to assign to a keyboard shortcut.
Select a single spline in the scene and execute the script. All knots should move to become aligned to the XY plane in the height of the spline’s pivot.
You could add an UI with options to align to other construction planes or to move the knots to the ground plane (by just using 0.0 instead of new_Z)