PDA

View Full Version : 3dsmax SDK adventure


f97ao
06-16-2006, 11:59 AM
I'm moving more and more into the 3ds Max SDK (c++). I thought I would start a thread where I share my thoughts about how to move to the SDK from a scripters perspective.

You are all welcome to chip in of course. :)

Some general thoughts:

The SDK is sometimes surprisingly simple to use for a scripter. There is a large number of functions that have identical names. Most of the poly functions, and object functions work almost like they do in MaxScript. What I find is normally tricky is to setup c++ so that you can use the functions to begin with. For example at this very moment I figured out how to send Nodes into c++ with MaxScript, the problem I'm having is how to use the Editable_Poly commands on it.

Some general tips:
- Download the max8 SDK help, even if you use max7. The help is WAY easier to use than it's for Max7 and there several nice tutorials.
- Start with the howto tutorials. I recommend especially the IntervalArray tutorial. This tutorial shows you how to extend maxScript functions.
- Use Visual Net 2003. Visual Studio 7 is ok too, but Net has a better environment. Visual Studio 2005 will soon be usable.

Performance notes:
- Slow return. I found out that it's actually very slow to return large arrays into MaxScript. For example I did a big loop that returns all the positions of all verts in an object. The loop in itself in c++ was extremely fast, around 15ms for a 1mil object, but returning the results took several hundreds of ms. This means we should only return big things if we really have to.

Myself I plan on focusing on adding MaxScript extentions in the beginning. So 90% of my code will remain scripts, but everything that needs big loops will be done in c++.


MaxScript and SDK comparison.


MaxScript benefits:
- Extremely easy to setup. Just write "box()" and you have an example of a script. It's way harder to start a c++ if you are new.
- Far easier to learn than C++. MaxScript work more like a human thinks, while C++ works more like a computer "thinks" so be prepared for heaps, pointers, binary trees, memory allocation etc.
- Simpler programs are far faster to write. I once wrote a scene information tool in 15minutes. That would have taken several hours in c++.
- Easy to test short progarms. In c++ you must restart max every time and will likely get many errors for "minor" things, variables need to be declared correctly, you can't mixed types, all the directories must be included etc.
- A consistent programming interface. If you want to change Editable_Poly you write something like polyOp.setVert ... while in C++ you have completely different libraries for almost the same object. There is MNMesh, there is EPoly, there is IEPoly, there is Edit_Poly, there is Editable_Poly, I think you get the picture.
- Variables are not type specific, so you can mix int, string, bool etc. This is however an advantage in bigger programs.
- Fast enough for most things that don't need to update in real time. In theory I think that 95% that is done with a button click is fast enough in MaxScript. For example, extrudes, loops. The things that are not fast enough is if you have things like bend modifier, noise modifier, or interactive extrude in viewport.
- Easy to create standard max interfaces. Just put a few buttons and checkboxes and you are up and running. C++ interfaces are WAY harder and need alot of coding.
- Shorter geometry/selection modifications work excellent. Examples are Face Loops, variants of extrude etc.
- Simpel debugging is easy in MaxScript, but more complex is not.
- Better documentation than the c++ SDK. The C++ SDK has very few examples.
- Easier to find comprehensive examples that can be changed to your own tools.
- Other peoples programs are quite easy to understand, while the c++ programs are almost incomprehensive unless you are very skilled in programming.

SDK Benefits
- loops will always be far faster. MaxScript can handle 100,000 loops ok, while c++ can handle loops with 100,000,000 objects ok. This is probably the best advantage with the SDK.
- complex algoritms are way faster. If you need to sort, or investigate complex geometry this will quickly kill maxScript
- larger geometry modifications that need bigger loops. For example you need to loop through 100,000 vertices and move them to somewhere. This is nearly impossible for Poly objects in maxScript, for Editable_Mesh objects it is possible though (since the mesh object don't update EVERY time the poly object is changed).
- Tools that need interactivity. If you need to have full control of the mouse and what it's doing you will quickly run into problem with MaxScript. To create even such a simple thing as interactive bevel is hard (is it even possible in a good way?) in MaxScript. Some Painting tools can be done that are good and fast though (because of the good PainterInterface).
- Advanced and powerful debug tools. You can easily break the code, and have all the locals printed, step through the code, etc. This is a BIG bonus
- Advanced Interfaces can only be created in C++. Here custom controlers can be created.
- Viewport graphic modifications can only really be done in C++. If you need to print text, draw lines (for example the isolines on turboSmooth), this can only be done in C++ in a good way (it will flicker and be slow in MaxScript).
- Multiple Undo in the Editor! Also things like context sensitive help, much better color coding etc. This can be done fairly good in maxScript if for example UltraEdit is used.
- Better connection to other tools, to send files with ftp, to connect to Photoshop, or Internet is much more powerful.
- Custom libraries can be downloaded that other people have written.
- Many silly hacks that must be done in MaxScript don't have to be done in C++, because c++ is so much faster. Normally you spend much time in MaxScript trying to figure out how you can fool max into being faster.
- Many slow problems can just be avoided in c++. For example if you move ONE vert in maxScript it will update all 500,000 vertices every single time. In c++ you can move 5000 vertices and THEN you update the remaining vertices. Guess what is the fastest?


/Andreas

f97ao
06-16-2006, 12:05 PM
Small things I found:

If you want to use strings you have to use max own string include.

#include "Numbers.h" // for handling of maxscript Integers and Floats
#include "Arrays.h" // for returning a maxscript array
#include "Strings.h" //For Strings

How to popup a messagebox, good to have in the start of the program so you are sure that it actually loads


MessageBox(NULL, _T("My Program started!!"), _T("Program Title!"), MB_OK);


Alot of the normal maxfunctions exist in a special interface. With it you can do alot of things like get the current selected objects, get the number of selected objects etc. Notice that when you write the -> after the interface all the methods and properties will popup so you can just scroll through them and look at the commands.

Interface *ip = GetCOREInterface();;
int a;
a=ip->GetSelNodeCount();

/Andreas

johanflood
06-19-2006, 09:39 AM
I am going to follow this thread

f97ao
06-19-2006, 10:30 AM
This is the complete code for a function to test if an object is an editable_poly object or an editable_mesh object:

To use it just write in MaxScript
ToolsGetPosArray($)

The C++ code:


#include "definsfn.h"
def_visible_primitive(ToolsGetPosArray, "ToolsGetPosArray");

Value* ToolsGetPosArray_cf(Value** arg_list, int count)
{

Interface* ip = GetCOREInterface();
int a;
//a=ip->GetSelNodeCount();

check_arg_count(ToolsGetPosArray, 1, count);
Value* pNode=arg_list[0];
INode *pnode=pNode->to_node();

//Verify that node is of a valid type
ObjectState os = pnode->EvalWorldState(0);
int sub_lv;

if (os.obj)
{
//Look at the super class ID to determine the type of the object.


Object* pobjBase = os.obj->FindBaseObject();

if( pobjBase->ClassID() == Class_ID(EDITTRIOBJ_CLASS_ID, 0) ) //Verify that the base object is an Editable Mesh
{
MessageBox(NULL, _T("Mesh Object!!"), _T("Testing!"), MB_OK);
}

if( pobjBase->ClassID() == EPOLYOBJ_CLASS_ID) //Verify that the base object is an Editable Poly
{
MessageBox(NULL, _T("Poly Object!!"), _T("Testing!"), MB_OK);
}
}


return &ok;
}

f97ao
06-19-2006, 10:32 AM
If you have a node that you got just like in the example above do like this to modify it's geometry. This just moves all the vertex points for an editable_mesh. The screen is also redrawn:


ObjectState os = pnode->EvalWorldState(0);

if (os.obj)
{
//Look at the super class ID to determine the type of the object.

if (os.obj->IsSubClassOf(triObjectClassID))
{

TriObject *tobj = (TriObject*)os.obj; // Get a mesh from input object
Mesh* mesh = &tobj->GetMesh();
int numVert = mesh->getNumVerts();
int numFaces=mesh->getNumFaces();
for (int i=0;i<numVert;i++) //Modify geometry
{
mesh->setVert(i,Point3(i,i,i));
}

mesh->InvalidateGeomCache(); //force geometry update
ip->ForceCompleteRedraw(true); //Update viewport (slower method)

}
}

Wahooney
06-19-2006, 02:23 PM
I've also been fidgeting in the SDK from time to time, I'm also interested in adding maxscript extensions, I'm actually in the process of adding low level access to dialogs' styles and ex-styles. So if I discover anything of interest I'll share it here too.

I must say at this point that anyone that wants to learn how to do stuff to max dialogs and ui controls should download rezn8's maxscript extension source, it's been very informative for me.

Here's a question I haven't been able to answer myself:

I want to make a function that will make a dialog the top most (like "Always on Top") of all the Max dialogs. I figured out how to do this by using SetWindowPos() which allows you to set the z-order to HWND_TOPMOST but this is the top most of all windows, meaning that if you task switch to another app it will be on top of that too!

Does anyone know how to make it the top most in the Max, but will fall back on task switches, preferably a method that doesn't require one to use callbacks for Max going into and out of focus?

Edit:
A method of accessing the UnwrapUVW modifier would also be handy. I'm not talking about the IUnwrapMod class but rather the modifier itself. I need access to the hWnd member so if you know how to get your hands on that, it would be cool too.

f97ao
06-20-2006, 08:51 AM
I've also been fidgeting in the SDK from time to time, I'm also interested in adding maxscript extensions, I'm actually in the process of adding low level access to dialogs' styles and ex-styles. So if I discover anything of interest I'll share it here too.


Yea, please share. There is really not that much tutorials/tips to be found about the max SDK. I will be putting up alot of small functions and more examples. I just figured out how to access the Editable_Poly object functions, but for some weird reason some of the functions are private (like grow selection??).

Mehehe, now I'm going to look at max9 :)
/Andreas

Wahooney
06-20-2006, 12:34 PM
Mehehe, now I'm going to look at max9 :)
/Andreas

You'd better be speaking figuratively... :scream:

BTW it seems that growing selections are not built into MNMesh, if you look in polyedit.cpp there is a function called EpfnGrowselection() it has all the grow functionality in there.

f97ao
06-20-2006, 12:59 PM
You'd better be speaking figuratively... :scream:

Nope, I just got a demonstration. :)


BTW it seems that growing selections are not built into MNMesh, if you look in polyedit.cpp there is a function called EpfnGrowselection() it has all the grow functionality in there.

Jupp, I'm just checking it out, but it was complaining that EpfnGrowselection() was private so I can't call it. Seems silly if it's really the case.
/Andreas

Wahooney
06-20-2006, 02:11 PM
Cool... are you bound by an NDA or can you start a thread? :deal:

Have you written mods yet? I still want to make a decent replacement for Substitute, Max's doesn't work too well.

f97ao
06-20-2006, 02:38 PM
Cool... are you bound by an NDA or can you start a thread? :deal:
I'm not saying nothing I'm afraid. Looks nice thought :)


Have you written mods yet? I still want to make a decent replacement for Substitute, Max's doesn't work too well.

You mean modifiers? Not yet, but it doesn't look that hard. Right now I'm focusing on creating extensions for Editable_Poly. If you have any requests please tell, I will try to make some public later on.

Damn, EpfnGrowselection is private to keep SDK compability with max6. Anyone got any ideas on how I can access functions like this anyway? Since I have the source code I could perhaps copy it from the Grow function. Ideas?

/Andreas

f97ao
06-20-2006, 08:31 PM
It's quite tricky actually to call the private functions. You have to define a FPParam that has the in parameters. And if there are return types you have to define a specific class for this too.

Ok, this is the way you have to call the poly functions that are private:



FPValue returnValue;
cd->Invoke(epfn_get_num_vertices, returnValue);
int numVertices = returnValue.i;


To get hold of the internal MNMesh object and for example get the position of all the vertices you can do like this:


PolyObject *pPolyObj =(PolyObject*) pobjBase;
EPoly *cd= (EPoly *)(pobjBase->GetInterface(EPOLY_INTERFACE));

//This is where you get the Mesh and loop for all the verts.
MNMesh *mm=cd->GetMeshPtr();
int numv=cd->GetMeshPtr()->numv;
Point3* posArray=new Point3[numv];

for (int i=0; i<(numv-1);i++)
{
posArray[i]=mm->v[i].p;
}



/Andreas

GallenWolf
06-22-2006, 04:44 AM
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

f97ao
06-22-2006, 09:02 AM
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

fabman
06-22-2006, 10:32 AM
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

f97ao
06-22-2006, 02:21 PM
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

GallenWolf
06-22-2006, 05:47 PM
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 :sad:

Alvin

f97ao
06-23-2006, 09:09 AM
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.

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

Wahooney
06-23-2006, 11:11 AM
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.

f97ao
06-23-2006, 01:01 PM
[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

GallenWolf
06-24-2006, 04:45 AM
Thank you Andreas!

Alvin

f97ao
06-26-2006, 11:22 AM
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

ObjectState
<-Object
<-BaseObject
<-Object
<-GeomObject
<-TriObject
<-Mesh - important


TriObject - 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

GumTree
06-28-2006, 06:24 AM
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

Wahooney
06-28-2006, 06:49 AM
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.

GumTree
06-28-2006, 07:36 AM
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();

3: Go through the stack using: 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

Wahooney
06-28-2006, 09:30 AM
Thanks for the tips Rogier, I'll give them a try asaic.

On a slightly different note, it seems the mov's on your home site are missing, I'd like to check them out some of them look really interesting.

Thanks again.

GumTree
06-29-2006, 01:28 AM
Thanks for the tips Rogier, I'll give them a try asaic.

On a slightly different note, it seems the mov's on your home site are missing, I'd like to check them out some of them look really interesting.

Thanks again.

Hmmm, that's a worry... All of them?
They seem to be there when I just checked a few. I think that some of the links of the 640x480 size movies may be dead as I didn't have the space to upload them. All the 320x240 mov's that load into the pages should be there. Maybe you're missing a codec?

Here are direct links to the first three, that way you can download them and view them with your preferred viewer... I believe I encoded them with the Sorensen Video 3 codec.

http://www.rogierfransen.com.au/GumData/movies/Ghost_CustomPFlowPlugin_320.mov
http://www.rogierfransen.com.au/GumData/movies/StreetBoat_CustomDynamicsPlugin_320.mov
http://www.rogierfransen.com.au/GumData/movies/RippingClothTest_CustomDynamicsPlugin_320.mov

Rogier

f97ao
07-04-2006, 10:01 AM
This is a handy function that will return the base Editable_Poly object. The good thing is that it works even though there are modifiers on the object. It does something very similar to:
$.baseObject
in MaxScript.

Notice that you muse use pnode->GetObjectRef() and then objectRef->FindBaseObject() to get the base object.

So far I have found that it's possible to improve the functions in MaxScripts alot, it's possible to make them far faster. However every time you think you are finished there always popup another tricky problem situation, the sdk has many more of these kinds of problems I'm afraid.

/Andreas

MNMesh* GetMNMeshFromNode(INode* pnode)
{
//The function returns a pointer to the MNMesh object of an Editable_Poly object. If it's not an editable_poly it will cause a MaxScript Exception

Object* objectRef=pnode->GetObjectRef();
Object* baseObject=objectRef->FindBaseObject();
MNMesh* mm=0;
TSTR idName;
baseObject->GetClassName(idName); //The name of the BaseObject Class for example Editable_Poly
bool isPoly=true;

if (baseObject->ClassID()==EPOLYOBJ_CLASS_ID) //Verify that node is an OBJECT
{
EPoly *cd=(EPoly *)(baseObject->GetInterface(EPOLY_INTERFACE));
mm=cd->GetMeshPtr();
}
else
isPoly=false;

if (isPoly ==false) { throw RuntimeError("The object is not an Editable_Poly");}

return mm;
}

f97ao
07-04-2006, 10:04 AM
This is a small function that returns the position of an Edge (so the center point of the edge).

As you see the vertices of an MNMesh (that you have for Editable_Polys) can be reached by
mm->v[index]



Point3 GetEdgePos(MNMesh* mm, int edgeNbr)
{
//Calculates the middle position of an Edge
Point3 EdgePos;
Point3* p1;
Point3* p2;

p1=&(mm->v[(mm->e[edgeNbr].v1)].p);
p2=&(mm->v[(mm->e[edgeNbr].v1)].p);
EdgePos.x=(p1->x+p2->x)/2;
EdgePos.y=(p1->y+p2->y)/2;
EdgePos.z=(p1->z+p2->z)/2;

return EdgePos;
}

f97ao
07-04-2006, 05:10 PM
To create a new Editable_Poly object (and a node) write like this (I will update this example more when I have found more about it):


PolyObject *newObj = CreateEditablePolyObject();
INode *node = GetCOREInterface()->CreateObjectNode(newObj);


Important.
If you get link errors when you add CreateEditablePolyObject then you must include the library functions.
This one needs the library:
Poly.lib

You add these libraries in the Solution Properties and
Linker/Input/Additinal Dependencies. My dependencies look like this for my current project:

mnmath.lib odbc32.lib odbccp32.lib comctl32.lib bmm.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib gup.lib paramblk2.lib Poly.lib

Here you can see that I'm using the math, mesh, maxscript and poly functions.

/Andreas

Wahooney
07-18-2006, 10:31 PM
Hey, I need to kind of bump this thread ;)

Does anyone know how to pass max names, ie. #thing, #hello, #whatever to a new function in an extension?

Thanks guys.

bernieLomax
07-19-2006, 01:18 AM
f97ao (member.php?u=101503)
does anyone happened to stumble in a way in max SDK to create a viewport window attached in a roullout, sorry to ask but i want to build a small lightmanager with some CG shading language included and i wanted to try and put it inside my rollout along with all the other light components...
hugs
bernielomax

f97ao
07-20-2006, 03:49 PM
Hey, I need to kind of bump this thread ;)

Does anyone know how to pass max names, ie. #thing, #hello, #whatever to a new function in an extension?

Thanks guys.

Nope, but I have tried. It doesn't work as Integer that is for sure.

Some of the things are very difficult in the sdk I must say. To create a new editable_poly object and to do it was sure is difficult. I have spent two weeks on that problem alone, but it looks like it will turn out fast in the end.

Regarding viewports in rollout, I think you will have serious problems with that I'm afraid. Max has many restrictions regarding viewports and it doesn't seem to be easy to create floating viewports etc. Has anyone drawn lines in the viewports by the way. I need to do that in a plugin, but haven't started yet. I remember that in MaxScript the lines always flickered, but this should hopefully be possible to solve in the sdk.

Is anyone running Visual 2005 with Max 8 by the way? I just installed 2005 here home, but I have problem compiling my plugins.

/Andreas

Wahooney
07-20-2006, 05:25 PM
You'd think that maxscript extensions would be one of the most documented in the maxsdk, I found a great reference, in the maxsdk\samples\maxscript\mxsagni. A great many maxscript exposures are define in this project, it's helped me quite a bit.

I figured out how to do the name thing.

You can type check with:
is_name()

and you can make a comparison with:
arr_list[i] == Name::intern("yournamehere");

You could probably do something better with a define and some enums though, but that's the basics.

Now I have a different question, I'm busy making a function that takes a ray defined in script, casts it through the scene and finds all objects that it intersects with it, returning : #(#(object, intersection ray (pos + normal), distance from ray origin), ...), I have a few uses for this, now I need to add a filter: option to it, does anyone know how to pass and execute a maxscript using variables in c++?

Thanks.

Dmaxer
07-24-2006, 01:05 PM
Im a newbe when its come to maxSDK so please forgive me if Im being real dumb . I have just installed the max SDK and installed Microsoft Visual Studio .NET 2003 . now Im trying to get the 3dsmaxPluginWizard to run . Ive edited the ABSOLUTE PATH parameter to reflect the new location of the 3dsmaxPluginWizard root directory. Ive aslo changed the first line of the 3dsmaxPluginWizard.vsz file from VSWIZARD 7.0 to VSWIZARD 7.1 .
but when I go to make a new project using the PluginWizard I get an error " Object with program ID VsWizard.VsWizardEngine cannot be created". Im running 3Dmax 8 by the way.
would anyone here know why Im getting this error ? any tips would be great .

thanks for reading

Dmaxer
07-24-2006, 01:25 PM
ok I sorted it , seems I needed to download an updated 3dsmaxPluginWizard :) . it seems to be working now :) . now I just need to learn how to use it .

AlpineMan
07-26-2006, 01:34 AM
...

Some general tips:
- Download the max8 SDK help, even if you use max7. The help is WAY easier to use than it's for Max7 and there several nice tutorials.

Thanks Andreas, we put a lot of work into it. I may have to update some of the tutorials though a bit (:) You always find things after reading them again that you'd like to change)

- Start with the howto tutorials. I recommend especially the IntervalArray tutorial. This tutorial shows you how to extend maxScript functions.
...


If there is anything you would like to be added just ask.

Chris J.

Wahooney
07-26-2006, 07:32 AM
AlpineMan:
So you're one of the people responsible for the state of the SDK?! I'd like to stand before you and shake your hand:beer: My SDing has taken a turn for the easy since max8's sdk help... SDK 7 was quite horrible :argh:

Anyway, something I noticed is that that there are a number of errors in the dllmain.cpp file part of the maxscript extension tutorial (my personal playground), there are some spaces missing between identifiers and variables, if one were to copy the tut letter for letter a whole bunch of errors crop up.

I hope you guys are adding even more stuff to SDK 9.

AlpineMan
07-26-2006, 04:18 PM
That tutorial was the first one I made, and went through lots of formats before it landed in HTML. So I can see that it had lots of problems. I'll fix it.

Other than that, I'm not on the team that does the SDK help anymore. My duties are elsewhere now. But I still have a bit of clout though to influence decisions.

Chris J.

Wahooney
07-26-2006, 05:18 PM
See if you can clout them into making some rollout control tutorials ;)

AlpineMan
07-27-2006, 04:38 AM
Well, have you seen the \maxsdk\howto\ui\customcontrols sample project?

| Purpose: To Demonstrate the use of the MAX Custom Controls.
|
| This plug-in puts up a rollup page in the utility panel with
| most of the custom controls. The comments in the source code
| document what is happening. Also see the Advanced Topics
| section for a description of the custom controls.
| Note: This plug-in does not use Parameter Maps to manage
| the user interface. Parameter Maps can simplify UI code
| for many plug-ins. See the Advanced Topics section on
| Parameter Maps for more details.

CGTalk Moderation
07-27-2006, 04:38 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.