using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Max;
using UiViewModels.Actions;
namespace Test.test.UndoRedo {
public class SRYRest_CUIActionAdapter : CuiActionCommandAdapter {
public override string ActionText => "SRYTestShape_command";
public override string Category => "SRYTestShape_command";
public override string InternalActionText => "SRYTestShape_command";
public override string InternalCategory => "SRYTestShape_command";
public override void Execute(object parameter) {
Test.SRYTestShape();
}
}
public static class Test {
public static void SRYTestShape() {
IGlobal g = Autodesk.Max.GlobalInterface.Instance;
IInterface14 core = g.COREInterface14;
var t = core.Time;
int num = core.SelNodeCount;
List<IINode> spls = new List<IINode>();
IHold theHo = g.TheHold;
theHo.SuperBegin();
theHo.Suspend();
if(num != 0) {
for(int i = 0; i < num; i++) {
IINode nod = core.GetSelNode(i);
if(nod.ObjectRef.IsShapeObject) {
if((nod.ObjectRef as ISplineShape) == null) {
IModifier edspl_mod = (IModifier)g.COREInterface.CreateInstance(SClass_ID.Osm, g.Class_ID.Create(96, 0));
var dObj = g.CreateDerivedObject(nod.ObjectRef);
dObj.AddModifier(edspl_mod, null, 0);
nod.ObjectRef = dObj;
g.COREInterface.CollapseNode(nod, true);
}
spls.Add(nod);
}
}
foreach(IINode s in spls) {
//saving original
List<ISpline3D> all3dLines = new List<ISpline3D>();
var origSs = (s.ObjectRef as ISplineShape);
var shp = origSs.Shape;
for(int spl = 0; spl < shp.SplineCount; spl++) {
ISpline3D spn = shp.GetSpline(spl);
int clo = spn.Closed();
int endVert = spn.Verts / 3;
ISpline3D pSpline = g.Spline3D.Create(1, 2, 0);
for(int i = 0; i < endVert; i++) {
pSpline.AddKnot(spn.GetKnot(i), -1);
}
pSpline.SetClosed(clo);
pSpline.ComputeBezPoints();
all3dLines.Add(pSpline);
}
//saving original
uint handle = s.Handle;
IPoint3 p = g.Point3.Create(0.0f, 0.0f, 0.0f);
IPoint3 iv = g.Point3.Create(1.0f, 0.0f, 0.0f);
IPoint3 ov = g.Point3.Create(0.0f, 1.0f, 0.0f);
ISplineKnot k = g.SplineKnot.Create();
k.Ktype = 2;
k.Ltype = 0;
k.Knot = p;
k.InVec = iv;
k.OutVec = ov;
var os = s.EvalWorldState(t, true);
var obj = os.Obj.ConvertToType(t, g.SplineShapeClassID);
s.ObjectRef = obj;
ISplineShape mySpline = obj as ISplineShape;
mySpline.AddKnot(0, k, 1);
ISpline3D sp = mySpline.Shape.GetSpline(0);
sp.ComputeBezPoints();
mySpline.Shape.UpdateSels(true);
mySpline.Shape.InvalidateGeomCache();
mySpline.UpdateSelectDisplay();
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand($"Lin=maxOps.getNodeByHandle {handle}; updateshape Lin;");
theHo.Resume();
theHo.Begin();
theHo.Put(new SRYRest(handle, all3dLines));
theHo.Accept("SRYundo");
theHo.Suspend();
}
}
theHo.Resume();
theHo.SuperAccept("SRYundo");
}
}
public class SRYRest : Autodesk.Max.Plugins.RestoreObj {
uint nHandle;
List<ISpline3D> lineData;
public SRYRest(uint hnd, List<ISpline3D> lines) {
nHandle = hnd;
lineData = lines;
}
public override void Redo() {
throw new NotImplementedException();
}
public override void Restore(bool isUndo) {
IINode activeLine = GlobalInterface.Instance.COREInterface.GetINodeByHandle(nHandle);
IObject ob = activeLine.ObjectRef;
ISplineShape origSS = (ob as ISplineShape);
IBezierShape origBS = origSS.Shape;
origBS.NewShape();
for(int s = 0; s < lineData.Count; s++) {
origBS.InsertSpline(lineData[s], s);
}
origBS.UpdateSels(true);
origBS.InvalidateGeomCache();
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand($"Lin=maxOps.getNodeByHandle {activeLine.Handle}; updateshape Lin;");
}
public override string Description {
get { return "SRYundo"; }
}
}
}
You can similarly save updated 3dSplines for redo, I also did not find maxscript updatedshape replacement in SDK