3ds Max .NET SDK and creating reference maker

2019-07-21 16:16发布

问题:

I have .Net DLL for Max with ui, and I want to react to parameter changes of some nodes in the viewport. The easiest solution that came up to me, was to create ReferenceMaker plugin and set reference for node I want to watch. According to the documentation it should be

 public class ReferenceListener : Autodesk.Max.Plugins.ReferenceMaker{ ... }

But when I create new instance of this class and try to set reference, it crashes on "Object reference not set to an instance of an object." When I try to debug it, I see that all baseclass attributes are null, so it seams ReferenceMaker plugin instance was not created in Max.

Finally I found MaxSharp source code here but using resulting dll let me to the same result and frankly the implementation is quiet the same as I had before. Trying to attach ReferenceListener to ReferenceTarget allways crashes beacause of nulls in base class. So I really don't know how to solve this, but maybe someone tried to create something like this and succedded? For now I'm thinking about writing those parameter changes callbacks to maxscript, and call .net form it, but it feels hacky.. I'm using Max 2014 (and MaxSharp is for 2013) but I did not found any differences mentioned in documentation and any help would be appreciated.

Thank you

UPDATE

So, I narrowed it down to really strange problem. I've created C++/CLI plugin, made ReferenceMaker class in C++ SDK and did .net wrapper to call the plugin form C#, but it still wasn't working with same symptoms.

It seems that wrong pointer address is stored inside Autodesk.Max wrapper objects, so this is the reason why it is failing. I did a comparison of pointer returned from .Net DLL and from C++ SDK, and they are always different by 64. And it is always like that.

C++/CLI code

IINode^ al =  Autodesk::Max::GlobalInterface::Instance->COREInterface->GetSelNode(0);
IReferenceTarget^ ak = (IReferenceTarget^)al;
ReferenceTarget* nativeTarget = (ReferenceTarget*)ak->Handle.ToPointer();
m_notifyListener->Test(nativeTarget);

C++ Max SDK code

void NotifyListener::Test(RefTargetHandle managedPointer)
{
     Interface* ip = GetCOREInterface();

     RefTargetHandle nativePointer = ip->GetSelNode(0);
     intptr_t P1 = (intptr_t)managedPointer;
     intptr_t P2 = (intptr_t)nativePointer ;
}

and than resulting variables are eg.

P1 = 1490452112
P2 = 1490452048

P2 is always smaller than P1 by 64. I would understand if those pointers were totally different, but this slight shift is really strange to me. Does anyone have any idea what is happening there? This is something I really don't get.

I need to test if the same behaviour is in Max 2013 or 2015 as I'm using 2014. I saw on some other forums that other people are complaining sample .net plugins are not working in 2014, so maybe this is the reason?

Thank you for any advice.