[Closed] SplineShape possible MXS extension
SplineShape is a base class for Editable Spline.
All spline shape methods exposed in mxs work with a node (editable spline) only, most of them (splineops) require selection and modifier panel opened.
there is no these limitations in the max sdk. you can work directly with SplineShape.
if anyone has a request about some methods that might improve mxs please tell me.
i will try to add them in Useful MXS Extensions thread on this forum http://forums.cgsociety.org/showthread.php?f=98&t=1089363 .
I have a spline tool that I did in maxscript that I’m slowly working on to port it to the sdk.
One function was to remove overlapping or double segments. The way this worked was…
– detach spline to segments
– first do a search to fine any double seg by their two knot postions (remove them)
– Attach an weld all segs
– see if spline has an index of 1 – if > than 1 still have a problem
– see if spline had a closed index shape (if yes delete all other indexes)
– find any indexs with one segment – detach them and color them red (might be bad)
you see where I’m going with this…
might be a thought might not
I think there are tons of spline ideas out there. I’m hoping to hear other peoples input too.
My 2 cents:
(
delete objects
sh = convertToSplineShape (circle wirecolor:green)
for j = 4 to 1 by -1 do refineSegment sh 1 j 0.5
for j = 8 to 2 by -2 do deleteKnot sh 1 j
)
RefineSegment <shape> <spline idx> <segment idx> <interpolations array>
RefineSegments <shape> <spline idx> <segments array bitarray> <interpolations array>
DeleteKnot <shape> <spline idx> <knot idx> [keepCurvature:<boolean>]
DeleteKnots <shape> <spline idx> <knots array bitarray> [keepCurvature:<boolean>]
Some more:
GetKnotTangent3D <shape> <spline idx> <knot idx>
GetKnotNormal3D <shape> <spline idx> <knot idx>
GetKnotBinormal3D <shape> <spline idx> <knot idx>
GetTangentCurve3D <shape> <spline idx> <segment idx> <param float> [pathParam:<boolean>] -- Already Implemented tangentCurve3D()
GetNormalCurve3D <shape> <spline idx> <segment idx> <param float> [pathParam:<boolean>]
GetBinormalCurve3D <shape> <spline idx> <segment idx> <param float> [pathParam:<boolean>]
All these methods can be done in MXS, but might be more convinient to have them in the core. I think it would be a good to have them shipped with Max.
why do you think that a bezier curve normal is a trivial thing? i might over-complicate things but it needs the second derivative. and i don’t remember that is exposed in max sdk.
probably we can find this calculation in the path constraint example (bank). but i didn’t have a chance to look at.
there should be a post stored on this forum where i’ve tried to calc it using pure mxs. but the solution was not perfect as i remember.
Because I already have it working in MXS.
The Path_Constraint as well as the Spacing Tool seems to fail on this. They booth seems to rely on the Tangent vector only. Look at “SplineExtrude.cpp”.
Here is a simple test showing how Parallel Transport works better than Path_Constraint:
(
delete objects
fn BuildTestShape color:green =
(
points = #([100,-50,0],[100,20,0],[70,50,0],[30,50,0],[0,20,0],[0,-20,0],[0,-50,30],[0,-50,70],[-30,-50,100],[-70,-50,100],[-100,-20,100],[-100,50,100])
sp = SplineShape wirecolor:yellow
addNewSpline sp
for j in points do addKnot sp 1 #smooth #curve j
updateShape sp
sp.render_displayRenderMesh = true
sp.render_rectangular = true
sp.render_length = 1.0
sp.render_width = 20.0
sp.steps = 6
return sp
)
fn ArrayPathConstraint path: =
(
obj = box length:10 width:50 height:4 lengthsegs:1 widthsegs:1 heightsegs:1 pos:[100,-50,0] dir:[0,1,0] wirecolor:red
centerpivot obj
obj.pos.controller = Path_Constraint follow:on constantVel:on axis:1 path:path
)
fn ArrayCustom path: ang: =
(
obj = box length:4 width:70 height:8 lengthsegs:1 widthsegs:1 heightsegs:1 pos:[100,-50,0] dir:[0,1,0] wirecolor:green
centerpivot obj
x=[1,0,0]; y=[0,1,0]; z=[0,0,1]
for step = 0.0 to 1.0 by 0.01 do
(
with animate on at time (step*100)
(
tangent = lengthTangent path 1 step
position = lengthInterp path 1 step
tmRot = matrix3 1
axis = cross z tangent
theta = atan2 (length axis) (dot z tangent)
tmRot.rotation = AngleAxis -theta (normalize axis)
x = normalize (x*tmRot)
y = normalize (y*tmRot)
z = tangent
obj.transform = prerotatez (matrix3 x y z position) ang
)
)
)
thePath = BuildTestShape()
ArrayPathConstraint path:thePath -- FAILS
ArrayCustom path:thePath ang:-9.5
timeConfiguration.playbackSpeed = 2
playanimation()
)
interesting…
here is a Transform_Script version:
fn PathScript node: path: angle:0 = at time 0
(
if node == unsupplied do
(
node = box length:5 width:80 height:10 lengthsegs:1 widthsegs:1 heightsegs:1 pos:[100,-50,0] dir:[0,1,0] wirecolor:orange
centerpivot node
)
scr = node.transform.controller = Transform_Script()
scr.addNode "path" path
scr.addConstant "ang" angle
scr.addConstant "x" x_axis
scr.addConstant "y" y_axis
scr.addConstant "z" z_axis
ss = "if iskindof path SplineShape then (
"
ss += " tangent = tangentCurve3D path 1 NT
"
ss += " pos = interpCurve3D path 1 NT
"
ss += " if NT == 0.0 do (
"
ss += " this.setConstant \"x\" x_axis
"
ss += " this.setConstant \"y\" y_axis
"
ss += " this.setConstant \"z\" z_axis
"
ss += " )
"
ss += " axis = cross z tangent
"
ss += " theta = atan2 (length axis) (dot z tangent)
"
ss += " rot = (angleaxis -theta (normalize axis)) as matrix3
"
ss += " x *= rot
"
ss += " y *= rot
"
ss += " z = tangent
"
ss += "
"
ss += " this.setConstant \"x\" x
"
ss += " this.setConstant \"y\" y
"
ss += " this.setConstant \"z\" z
"
ss += "
"
ss += " prerotatez (matrix3 x y z pos) ang
"
ss += ") else (Matrix3 1)
"
scr.setExpression ss
scr
)
Interesting…
Now back to re-write that awful Path_Constraint controller.
And a better Spacing Tool wouldn’t be bad at all. Well, at least until Max 2016, now we have plenty of MCGs for that.
ang: -9.5???
Is there a way to find this angle to align the object local X axis with the ‘transversal’ direction of the spline? Two near values from the origin?
Yes, it hasn’t been a very clear question. Forget about it. I’m just rewieving old codes and algorithms…