Community
3ds Max Forum
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Spline shape not updated correctly in tool

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
dswahn
1530 Views, 12 Replies

Spline shape not updated correctly in tool

I recently produced a script that can assist in extending and inserting Spline Knots depending on your view. This functionality now works flawlessly, but there is a side-effect that I cannot figure out, namely for some reason the shape isn't updated after the knot insertion - meaning if I use any native operation (such as Outline), the shape jumps back to the state it had prior to my knot insertions.
 
This is despite I'm using UpdateShape() in the right places, which supposedly should update the shape content cache. As you can see in the attached video it is only when I for example move a knot after the script operation that it seems like the shape content cache is updated, and any subsequent operations works as expected.
 
I know Maxscript and splines are not the best buddies all the time, but is there a potential solution to my problem? Or is this just another native spline bug in desperate need of fixing?
 
Thanks!
Tags (2)
Labels (2)
12 REPLIES 12
Message 2 of 13
Swordslayer
in reply to: dswahn

UpdateShape would be the right one if you were using addKnot+setKnotPoint but it looks like you're using splineOps. You could try some of the SDK methods like InvalidateGeomCache. In mxs, it could look like this:

 

iGlobal = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
obj = iGlobal.Animatable.GetAnimByHandle (getHandleByAnim $.baseObject)
if isProperty obj #InvalidateGeomCache do obj.InvalidateGeomCache()

But given that it looks more like the command mode of the splineOps isn't finished properly, it might be enough to call some of the 'max' commands when you're finished to force command mode change, for example

max select

 

Message 3 of 13
dswahn
in reply to: dswahn

I will try, thank you.

Message 4 of 13
dswahn
in reply to: dswahn

Also, I am already implementing the max select to end the splineOp. So the problem exists despite this.

Message 5 of 13
dswahn
in reply to: Swordslayer

Unfortunately the obj.InvalidateGeomCache() approach returns undefined

I cannot verify whether this works or not.

Message 6 of 13
Swordslayer
in reply to: dswahn

The return type is void so yeah, it will only return undefined. You should be able to test if the outline works after calling it or not.

Message 7 of 13
dswahn
in reply to: dswahn

Sadly it didn't solve the problem. I get the same issue (see attached video).

Message 8 of 13
Swordslayer
in reply to: dswahn
Message 9 of 13
dswahn
in reply to: dswahn

After trying with just splineOps.startInsert $ on a spline object I realized that the bug does not happen.

 

I pinpointed the issue to being the max select command. If I remove max select from my code I can perform an Outline operation as expected.

So while the max select helps me cancel the Insert operation, it somehow messes up the content of the spline in the process, so any operation applied after the Insert results in the spline state before the Insert.

At least the problem has been pinpointed, but the question is how to solve it?
I kind of need the max select in order to cancel the Insert operation. Otherwise the user needs to right-click two times which is a bit annoying...

Message 10 of 13
Swordslayer
in reply to: dswahn

Still no code to reproduce so this is my last contribution here. Since all splineOps do (and why I avoid using them at all) is that they push buttons in the UI, you can do the same and push button in the UI to deactivate it.

 

 

(
	local iGlobal = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
	local cpHWnd = iGlobal.UtilGetCoreInterface.CommandPanelRollup.HWnd
	local cpChildren = windows.getChildrenHWnd cpHWnd
	local insertHWnd = for child in cpChildren
		where UIAccessor.getWindowResourceID child[1] == 1042 do
			exit with child[1]
	if isKindOf insertHWnd Number do UIAccessor.pressButton insertHWnd
)

 

Message 11 of 13
dswahn
in reply to: dswahn

I'm sorry if I have not provided any code, while I was putting together an example of the code I realized another important thing that solved the issue. I had put max select within an undo off(), and apparently this confused the process.

 

The thing is that I put the process of deleting the temporary grid outside the undo context so that if you undo this temporary grid won't pop back into existence. All I had to do was to change this:

undo off
(
activeGrid = oldGrid
delete tempGrid
max select
)

 

To this:

 

undo off
(
activeGrid = oldGrid
delete tempGrid
)
max select

 

Also the reason why I use splineOps.startInsert is because it provides simple undo for the changes you make to the spline. There is a long-persisting bug or behaviour in max where changes to splines made by maxscript doesn't produce an undo context, meaning you cannot undo the changes. Using splineOps.startInsert gives you that undo context.

I can however conclude that the problem has been solved.
Thanks for the input @Swordslayer !

Message 12 of 13
Swordslayer
in reply to: dswahn


@dswahn wrote:

There is a long-persisting bug or behaviour in max where changes to splines made by maxscript doesn't produce an undo context, meaning you cannot undo the changes. Using splineOps.startInsert gives you that undo context.


Call replaceInstances $.baseObject $.baseObject after your operation to get an undo record with spline changes.

Message 13 of 13
dswahn
in reply to: Swordslayer

Thank you. I read previously that one can make the changes on a clone of the spline, instance that to the original object (and delete the clone) under the same undo to force an undo, but your suggestion looks obviously simpler.

 

I will try it.

Thanks again.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report