Notifications
Clear all

[Closed] [SDK] creating spline shape

Hi,
I’m trying to create a simple spline shape with 2 knots using SDK. In MaxScript it’s something like this:

ss=SplineShape()
addNewSpline ss
addKnot ss 1 #corner #curve [0,0,0]
addKnot ss 1 #corner #curve [1,0,0]
UpdateShape ss

What’s the equivalent of this code in c++?

5 Replies
SplineShape* pSplineShape = new SplineShape;
BezierShape& bs = pSplineShape->GetShape();
Spline3D* pSpline = bezShape.NewSpline();

Point3 p(0, 0, 0);
SplineKnot k(KTYPE_CORNER, LTYPE_CURVE, p, p, p);
pSpline->AddKnot(k);

p = Point3(1, 0, 0);
k = SplineKnot(KTYPE_CORNER, LTYPE_CURVE, p, p, p);
pSpline->AddKnot(k);

bs.UpdateSels();

i m trying to do same in C#

            ISplineShape pSplineShape = Global.SplineShape.Create();
            IBezierShape bs = Global.BezierShape.Create(pSplineShape.Shape);
            ISpline3D pSpline = bs.NewSpline(0, 1, 0);


            IPoint3 p = Global.Point3.Create(0f, 0f, 0f);
            ISplineKnot k = Global.SplineKnot.Create(); k.Ktype = 1; k.Ltype = 0; k.Knot = p; k.InVec = p; k.OutVec = p;
            pSpline.AddKnot(k, -1);

            p.Set(1f, 0f, 0f);
            k.Ktype = 1; k.Ltype = 0; k.Knot = p; k.InVec = p; k.OutVec = p;
            pSpline.AddKnot(k, -1);

            pSpline.SetClosed(0);
            pSpline.ComputeBezPoints();

            bs.UpdateSels(true);
            bs.InvalidateGeomCache();


How can i  get   IShapeObject  for  CreateObjectNode()  now
thanks

theres a good example in mesh/editable_poly project in the examples… look for

CreateCurveFromMeshEdges (MNMesh & mesh, INode *onode, Interface *ip, TSTR & name, bool curved, DWORD flag)

may as well post the whole thing

bool CreateCurveFromMeshEdges (MNMesh & mesh, INode *onode, Interface *ip, TSTR & name, bool curved, DWORD flag) {
	SuspendAnimate();
	AnimateOff();
	HoldSuspend hs; // LAM - 6/12/04 - defect 571821

	SplineShape *shape = (SplineShape*)GetSplineShapeDescriptor()->Create(0);	
	BitArray done;
	done.SetSize (mesh.nume);

	for (int i=0; i<mesh.nume; i++) {
		if (done[i]) continue;
		if (mesh.e[i].GetFlag (MN_DEAD)) continue;
		if (!mesh.e[i].GetFlag (flag)) continue;

		// The array of points for the spline
		Tab<Point3> pts;

		// Add the first two points.
		pts.Append(1,&mesh.v[mesh.e[i].v1].p,10);
		pts.Append(1,&mesh.v[mesh.e[i].v2].p,10);
		int nextv = mesh.e[i].v2, start = mesh.e[i].v1;

		// Mark this edge as done
		done.Set(i);

		// Trace along selected edges
		// Use loopcount/maxLoop just to avoid a while(1) loop.
		int loopCount, maxLoop=mesh.nume;
		for (loopCount=0; loopCount<maxLoop; loopCount++) {
			Tab<int> & ve = mesh.vedg[nextv];
         int j;
			for (j=0; j<ve.Count(); j++) {
				if (done[ve[j]]) continue;
				if (mesh.e[ve[j]].GetFlag (flag)) break;
			}
			if (j==ve.Count()) break;
			if (mesh.e[ve[j]].v1 == nextv) nextv = mesh.e[ve[j]].v2;
			else nextv = mesh.e[ve[j]].v1;

			// Mark this edge as done
			done.Set(ve[j]);

			// Add this vertex to the list
			pts.Append(1,&mesh.v[nextv].p,10);
		}
		int lastV = nextv;

		// Now trace backwards
		nextv = start;
		for (loopCount=0; loopCount<maxLoop; loopCount++) {
			Tab<int> & ve = mesh.vedg[nextv];
         int j;
			for (j=0; j<ve.Count(); j++) {
				if (done[ve[j]]) continue;
				if (mesh.e[ve[j]].GetFlag (flag)) break;
			}
			if (j==ve.Count()) break;
			if (mesh.e[ve[j]].v1 == nextv) nextv = mesh.e[ve[j]].v2;
			else nextv = mesh.e[ve[j]].v1;

			// Mark this edge as done
			done.Set(ve[j]);

			// Add this vertex to the list
			pts.Insert(0,1,&mesh.v[nextv].p);
		}
		int firstV = nextv;

		// Now weve got all th points. Create the spline and add points
		Spline3D *spline = new Spline3D(KTYPE_AUTO,KTYPE_BEZIER);					
		int max = pts.Count();
		if (firstV == lastV) {
			max--;
			spline->SetClosed ();
		}
		if (curved) {
			for (int j=0; j<max; j++) {
				int prvv = j ? j-1 : ((firstV==lastV) ? max-1 : 0);
				int nxtv = (max-1-j) ? j+1 : ((firstV==lastV) ? 0 : max-1);
				float prev_length = Length(pts[j] - pts[prvv])/3.0f;
				float next_length = Length(pts[j] - pts[nxtv])/3.0f;
				Point3 tangent = Normalize (pts[nxtv] - pts[prvv]);
				SplineKnot sn (KTYPE_BEZIER, LTYPE_CURVE, pts[j],
						pts[j] - prev_length*tangent, pts[j] + next_length*tangent);
				spline->AddKnot(sn);
			}
		} else {
			for (int j=0; j<max; j++) {
				SplineKnot sn(KTYPE_CORNER, LTYPE_LINE, pts[j],pts[j],pts[j]);
				spline->AddKnot(sn);
			}
			spline->ComputeBezPoints();
		}
		shape->shape.AddSpline(spline);
	}

	shape->shape.InvalidateGeomCache();
	shape->shape.UpdateSels();

	hs.Resume();
	INode *node = ip->CreateObjectNode (shape);
	hs.Suspend();

	INode *nodeByName = ip->GetINodeByName (name);
	if (nodeByName != node) {
		if (nodeByName) ip->MakeNameUnique(name);
		node->SetName (name);
	}
	Matrix3 ntm = onode->GetNodeTM(ip->GetTime());
	node->SetNodeTM (ip->GetTime(),ntm);
	node->FlagForeground (ip->GetTime(),FALSE);
	node->SetMtl (onode->GetMtl());
	node->SetObjOffsetPos (onode->GetObjOffsetPos());
	node->SetObjOffsetRot (onode->GetObjOffsetRot());
	node->SetObjOffsetScale (onode->GetObjOffsetScale());	
	ResumeAnimate();
	return true;
}

thank you, i’ll look at it

working code

            ISplineShape pSplineShape = Global.COREInterface.CreateInstance(SClass_ID.Shape, Global.SplineShapeClassID) as ISplineShape;
            IBezierShape bs = pSplineShape.Shape;
            ISpline3D pSpline = bs.NewSpline(0, 1, 0);


            IPoint3 p = Global.Point3.Create(0f, 0f, 0f);
            ISplineKnot k = Global.SplineKnot.Create(); k.Ktype = 1; k.Ltype = 0; k.Knot = p; k.InVec = p; k.OutVec = p;
            pSpline.AddKnot(k, -1);

            p.Set(1f, 0f, 0f);
            k.Ktype = 1; k.Ltype = 0; k.Knot = p; k.InVec = p; k.OutVec = p;
            pSpline.AddKnot(k, -1);

            pSpline.SetClosed(0);
            pSpline.ComputeBezPoints();


            bs.UpdateSels(true);
            bs.InvalidateGeomCache();

            Global.COREInterface.CreateObjectNode(pSplineShape);

but AddSpline function crashes max. thanks