Notifications
Clear all

[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 .

14 Replies

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

it looks like a tool it’s not a point for mxs extension

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.

2 Replies
(@denist)
Joined: 1 year ago

Posts: 0

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.

(@polytools3d)
Joined: 1 year ago

Posts: 0

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()
 )
1 Reply
(@denist)
Joined: 1 year ago

Posts: 0

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?

2 Replies
(@polytools3d)
Joined: 1 year ago

Posts: 0

I am sorry but I don’t understand the question.

(@aaandres)
Joined: 1 year ago

Posts: 0

Yes, it hasn’t been a very clear question. Forget about it. I’m just rewieving old codes and algorithms…