Notifications
Clear all

[Closed] Sdk basic modifier

Great Klvnk, ChannelMask fixed it!!

I couldn’t get the GetPipeAsPoly function to work. I tested with a break, it executed into this part of the function.

	if (pipe->CanConvertToType(polyObjectClassID))
		poly = static_cast<PolyObject *>(pipe->ConvertToType(t, polyObjectClassID));
	else

so should have returned a PolyObject correct? Then when applying to editmesh in max nothing happens. Only if it is converted to a editpoly.

void TimberBoarding_mod::ModifyObject(TimeValue t, ModContext& mc, ObjectState* os, INode* node)
{
	Interval valid = GetValidity(t);
	Object *obj = os->obj;
	if (!obj) return;

	Interval iv = FOREVER;
	iv &= obj->ChannelValidity(t, GEOM_CHAN_NUM);
	iv &= obj->ChannelValidity(t, TOPO_CHAN_NUM);

	float tention;
	pblock->GetValue(pb_spin, t, tention, valid);
	Point3 axis = Point3(0.0f, 0.0f, 1.0f);

	PolyObject *pobj = GetPipeAsPoly(t, obj);

	ModifyPolyObject(pobj, axis, tention);

	obj->UpdateValidity(GEOM_CHAN_NUM, iv);
	obj->UpdateValidity(TOPO_CHAN_NUM, iv);

}

How in the heck would I get the object bounding box min & max, dose this have to be passed from maxscript?

what happened to this bit ?

if(polyobj != os->obj) // new object push it into the pipe
	{
		os->obj = polyobj;
		os->obj->UnlockObject();
	}

what’s wrong with using

MNMesh::getBoundingBox 

?

Sorry Klvnk, I forgot to copy that, my mistake. cut works great now!! Totally fixed!!

I’m a total newb sorry, but how the heck do I get the min max values like maxscript to use from getBoundingBox ()?

This has all helped me so much, thanks for taking the time!

 void TimberBoarding_mod::ModifyObject(TimeValue t, ModContext& mc, ObjectState* os, INode* 
  node)
 
  {
Interval valid = GetValidity(t);
Object *obj = os->obj;
if (!obj) return;

Interval iv = FOREVER;
iv &= obj->ChannelValidity(t, GEOM_CHAN_NUM);
iv &= obj->ChannelValidity(t, TOPO_CHAN_NUM);

float tention;
pblock->GetValue(pb_spin, t, tention, valid);
Point3 axis = Point3(0.0f, 0.0f, 1.0f);

PolyObject *polyobj = GetPipeAsPoly(t, obj);
if (polyobj != os->obj) // new object push it into the pipe
{
	os->obj = polyobj;
	os->obj->UnlockObject();
}

// get the mesh and slice
MNMesh& pmesh = polyobj->GetMesh();

//Trying to get min max values
Box3 bbox = pmesh.getBoundingBox();

int NumCuts = 10; //will be float spinner

//pmesh.min; cant use this

pmesh.Slice(axis, tention, 0.0, false, true);

obj->UpdateValidity(GEOM_CHAN_NUM, iv);
obj->UpdateValidity(TOPO_CHAN_NUM, iv);


  }

where mxs gets it from…

   bbox.Min();
   bbox.Max();

I’m a total newb sorry

not to worry, the best advice I can give is use visual studios find in file functionality (link it to the maxsdk folder) to search for functions/methods for examples of usage. Also the mxsagni project is a treasure trove of howtos as is has the source for a lot of mxs in it.

I use grepWin a lot for exact this purpose. It supports regex. Also there’s FileLocatorPro which is lightning fast

Astro Grep is my favorite.

Thanks guys, checking out those files! So close, just need to figure out the face extrudes and then add the spinners

I’m still fiddling with getting all faces to extrude. I’ve found some code you posed. But adapting to my needs I’m unsure. I haven’t found much in samples. There are some in maxscrip polyop.cpp but how to use them and get a facelist I’m lost.

This is what I’ve tried to do.

void TimberBoarding_mod::ModifyObject(TimeValue t, ModContext& mc, ObjectState* os, INode* node)
{
	Interval valid = GetValidity(t);
	Object *obj = os->obj;
	if (!obj) return;

	Interval iv = FOREVER;
	iv &= obj->ChannelValidity(t, GEOM_CHAN_NUM);
	iv &= obj->ChannelValidity(t, TOPO_CHAN_NUM);

	float tention;
	pblock->GetValue(pb_spin, t, tention, valid);
	Point3 axis = Point3(0.0f, 0.0f, 1.0f);

	PolyObject *polyobj = GetPipeAsPoly(t, obj);
	if (polyobj != os->obj) // new object push it into the pipe
	{
		os->obj = polyobj;
		os->obj->UnlockObject();
	}

	// get the mesh and slice
	MNMesh& pmesh = polyobj->GetMesh();

	//get bounding box
	Box3 bbox = pmesh.getBoundingBox();
	Point3 SliceMax = bbox.Max();
	Point3 SliceMin = bbox.Min();

	//vars as per maxscript
	int Xmins = SliceMax.x - SliceMin.x;
	float XEnteredNo = tention; //cutting distance
	int XBoardNo = Xmins / XEnteredNo;
	int xchops = XBoardNo; //number of slices

	Point3 slicelen1 = SliceMax - SliceMin;
	Point3 slicelen = slicelen1 / xchops;

	//slice loop
	for (int i = 0; i < xchops; ++i)
	{
		int slicepoint = (SliceMin.z + (i*slicelen.z));
		pmesh.Slice(axis, slicepoint, 0.0, false, false);
	}
	

	//extrude all faces
	pmesh->faceSel = faces;
	pmesh->ExtrudeFaces();
	int nVerts = pmesh->getNumVerts();
	if (nVerts != 0)
	{
		// collect the verts in the "extruded" faces
		BitArray verts(nVerts);
		for (int i = 0; i < pmesh->getNumFaces(); ++i)
		{
			if (!pmesh->faceSel[i]) continue;
			Face *f = &pmesh->faces[i];
			for (int j = 0; j < 3; j++) verts.Set(f->v[j]);
		}
		// do the shift
		for (int i = 0; i < pmesh->nVerts; ++i)
		{
			if (verts[i])
			{
				// compute the shift.... for each vert
			}
		}
	}
	//END

	obj->UpdateValidity(GEOM_CHAN_NUM, iv);
	obj->UpdateValidity(TOPO_CHAN_NUM, iv);


}

I’ve managed to find some code to create the new extrude faces but I’m having trouble moving them.

float distance = 10;
bool ret = false, topoChange = false;

MNChamferData chamData;
MNMesh* mm = &pmesh;
MNTempData mtd(mm);
for (int i = 0; i < mm->numf; i++) {
	mm->f[i].SetFlag(MN_USER);
}
MNFaceClusters fClust(*mm, MN_USER);

topoChange = mm->ExtrudeFaces(MN_USER);

if (topoChange) {

	// Move vertices, not working!
	for (int i = 0; i < pmesh.numv; i++) {
		if (pmesh.v[i].GetFlag(MN_DEAD)) continue;
		pmesh.v[i].p += chamData.vdir[i] * distance;
	}

	mtd.Invalidate(TOPO_CHANNEL);
	mtd.freeBevelInfo();
	mtd.freeAll();
}
if (ret) mm->GetExtrudeDirection(mtd.ChamferData(), MN_USER);

Got it to work!!! finally

All I need now is to make the offset of the slice correspond to the actual scene units, but great, so pleased.

Thanks for all the help guys! couldn’t have figured it out without the help!!

Page 2 / 3