Hey all!
Glad there is an active thread on the max sdk – I’m halfway through my c++ refresher course, and will be getting into windows programming soon. Can’t find a copy of VC7.0 yet though, still on VC6. Ebay time I guess
I’m going to be re-formating my hdd soon, and I’d like to know if I should get a copy of XP Pro, or continue using (gasp) Win2k. I also had a recent mainboard failure, and changed camps from intel to amd, i don’t know if this will affect sdk programming.
Thanks for any advice!
Regards,
Alvin
The most tricky stuff when programming max is the max API itself, you don’t need to know that much c++ or windows programming to do many things. VC7.0 is ok, but 2003 NET is probably better, that is what I’m using. Win2k should work fine too, and AMD won’t cause problems either. Good luck
/Andreas
Great thread F97ao, I’m trying to start creating my own plugins with the SDK, but it seems quite an challenge, so, thanks for all the info you’re posting!.
Cheers
Thanks. I just try to contribute with what I self would like to have. Check out my first post, I added alot of stuff there.
This shows how to work with BitArrays and and make selections on Editable_Polys.
//mm is an MNMesh
BitArray vsel(numv);
vsel.ClearAll();
for (i=0;i<=(targetCount-1);i++)
{
vsel.Set(powerPosArray[i].index);
//mm->v[i].SetFlag(MN_SEL, true);
}
mm->VertexSelect(vsel);
/Andreas
Andreas, thanks for the reply! I’m curious about the compiler though, do you mean it is ok to use .net 2003? ’cause the 8 sdk readme states it needs vc7 which is from .net 2002? Another thread mentioned when programming for the sdk, even vc7.1 should not be used.
I hunted through my local software shops, they only have 2005, i think, and told me 2003 is not available, even if I wanted to special order it
btw, I’m still new to these win32 compilers thing – last I did C++ was on unix 🙁
Alvin
I’m not sure if 2005 works actually, I think it does, but I’m not completely sure. We use 2003 here at work so it definetly works (the application wizard doesn’t though). VC7 should work fine too, I used it in the past. The max8 sdk help is pretty good at explaining how to setup the plugins so read the introduction carefully. Also remember to use the Hybrid mode and not the Debug mode. When you have a visual studio open the vc solution for InterValarray. Then open the project settings, here you have to change many paths for example the include path, the lib path etc (it’s all in the help). Then you can compile it. Remember the sdk is not easy to learn, so if it’s more limited programs you plan on doing the maxScript is the way to go. You can read more on the sparks forum about different compilers and the sdk.
/Andreas
I’m busy writing a plugin that finds vertex velocities or animated meshes. I need to get an Objects ObjectState at two different times. All I have is the ObjectState passed to me in the ModifyObject () function. Using this ObjectState I need to get the ObjectState of the same Object but one frame ago… still with me?
My code looks like this:
// I have been passed os by the modifier
TimeValue tpf = GetTicksPerFrame(); // Get the ticks per frame
t = GetCOREInterface()->GetTime(); // Get the current time
Object *obj = os->obj; // Get the object from the current object state
ObjectState os2 = obj->Eval (t - tpf); // Get the object state of the object one frame ago
But I always end up getting the same object state, making my vertex differences of the polygon objects derived from the two different OS’s 0!
This is driving me nuts…
I hope that this has made some sort of sense to you guys.
Hey Wahooney,
The object from os.obj is not the same as the Max object. You would normally have to work with INode::EvalWorldState(t) (from memory…) for this purpose.
Apart from that: What you’re trying to do is actually quite hard within a modifier. Just imagine if it would work:
At time t the pipeline of the node is evaluated,gets to your modifier…
which requires the pipeline at to be evaluated at t-1
which requires the pipeline at to be evaluated at t-2
etc… until the beginning of the universe…
I am not sure what you want exactly, but a solution could be create a procedural geometry plugin that has a reference to a Node (INode) as parameter. Then you can safely call pNode.EvalWorldState at times t and t-1.
Hope this helps,
Rogier
[QUOTE=Wahooney]I’m busy writing a plugin that finds vertex velocities or animated meshes. /QUOTE]
I will try to look at the code later to see what is going wrong.
Some general tips on Visual Net
For posting debug information to the Output window (same as writing print in MaxScript):
int numPoints=20;
float debugFloat=5.5;
DebugPrint("NumberOfPoints: %.i %.2f", numPoints, debugFloat);
Notice that the %.i will print an integer, and the %.2f will print a float with 2 decimals.
Also don’t remember the Locals window that post all of the variables.
You can add Watches too by writing the variable names. If it’s an array you should write like this:
VariableName,10
Then the Watch will add the first 10 elements of the array.
Another tip is to press Shift+B to build the code, if it doesn’t have any errors press F5.
/Andreas
Here is an overview of the different classes that you need when working with object modifications.
There are many layers of objects that you need to access when modifying geometry. Some are not so useful. Here is an overview of the important ones (that I’ve found so far).
EDITABLE_POLY
ObjectState
<-BaseObject
<-Object
<-GeomObject
<-PolyObject
<-MNMesh – important
ObjectState
<-Object
*BaseObject
<-EPoly – important
ObjectState
Can manipulate the object transform matrix (for moving, rot etc). Also used as a starting point to return the baseobjects.
BaseObject
This is the top of an object. Has some functions for Set Selections, getting Hit tests for handling if the object is clicked, transformations like move, rotate, scale.
Object
Below BaseObject. Can convert object, apply uvw maps, Has access to geometric objects, cameras and lights, can Lock the object. Has many low level functions that you probably don’t need like GetXTCObjectBranchID.
GeomObject
Few useful methods.
PolyObject
Few useful methods. GetMesh is the most useful one to get the MNMesh.
MNMesh
Very useful class for complex geometry modifications. All the verts, edges and faces can be found here, faces can be created, copied, chamfer, tesselation, deleteFace, Weld. This seem to be the true access where you can do whatever you want to the poly objects. The functions are not that complex so be prepared to do most of the work yourself. A tip is to check in the editable_poly.cpp files to see exactly how all the EPoly methods actually work with the MNMesh.
MNMesh has the classes, MNVert (has the point3 pos of the vert), MNEdge and MNFace.
EPoly – inherited from BaseObject
This is most similar to polyOp in MaxScript and is very useful. Here you find, EdgeLoops, extrusions and all the properties that we have in the Editable_Poly floater. Very useful if you need to have access to the normal poly objects. One risk with these methods is that they can be slow if you need them for specific tasks. If you for example want to create a method that grows the selection 10 times you are better off doing this with MNMesh since it will be faster.
If you have an object you get the Epoly interface like this:
Object* pobjBase = os.obj->FindBaseObject();
EPoly *cd= (EPoly *)(pobjBase->GetInterface(EPOLY_INTERFACE));
Call it like this:
cd->SetEPolySelLevel(4);
EDITABLE_MESH
[left]
ObjectState
<-Object
<-BaseObject
<-Object
<-GeomObject
<-TriObject
<-Mesh – important
[b]
TriObject [/b]- Inherited from GeomObject
Has few methods, is mostly used to return the Mesh object.
Mesh
Lots of functions for working with editable_mesh objects. DeleteSelected, Facenormal, access to the verts/faces (you can’t get the edges directly for mesh objects), vertHide etc are all to be found here.
/Andreas
[/left]
Yeah, I kinda figured that, but isn’t it possible to evaluate an object up to a certain point in the stack? That way I’d be able to reference the object without my modifier, or any subsequent modifiers, being executed.
Maybe… possibly…
In that case in your ModifyObject function:
1: Get the actual node you are dealing with. http://sparks.discreet.com/knowledgebase/public/solutions/node_handle.htm
2: Get the derived object from the node with
IDerivedObject* pDerObj = (IDerivedObject*) pNode.GetOjbectRef();
[font=Verdana]3: Go through the stack using: [/font]pDerObj.GetModifier(imod) and turn off all modifiers on top of yourself. Do this with Modifier::EnableMod(…).
There is a function IDerivedObject::Eval(t,modIndex) which would be useful to avoid this trouble. However I tried using that in another project and it did not seem to work (Max 7.)
4: Call pNode.EvalWorldState(t-tpf) to get what you need.
5: Turn all the modifiers back on.
It could work… I am curious to find out.
Good luck,
Rogier