C++ Utility plugin

C++ Utility plugin

istan
Advisor Advisor
2,861 Views
25 Replies
Message 1 of 26

C++ Utility plugin

istan
Advisor
Advisor

I have a utility plugin with ClassDesc2 and ParamBlk2 and several rollouts in the GUI. I see all paramblk properties from MXS via:  showClass "myplug.*"

But how can I get access to these utitlity parameters from MXS or C++ ?

0 Likes
Accepted solutions (2)
2,862 Views
25 Replies
Replies (25)
Message 2 of 26

omidt_gh
Enthusiast
Enthusiast

There is a couple of steps you need to follow.
First, you need to access the base class you want to access for example object/material/maps

Then, you need to get the param block from the base class

And at last, you can access the final parameters you want one by one.

For example, if you want to access the material/map parameters and return it as a string you need to do it like this:

std::string MaxToLuxMaps::getFloatByID(::Mtl* mat, ::Texmap* tex, int refno)
{
	float value = 0.0f;
	std::string stringValue = "";
	IParamBlock2 *pBlock = NULL;

	if (mat != NULL)
		pBlock = mat->GetParamBlock(0);
	else
		pBlock = tex->GetParamBlock(0);

	if (pBlock != NULL)
	{
		value = pBlock->GetFloat(refno, GetCOREInterface()->GetTime());
		stringValue = lmaputil->floatToString(value);
	}
	return stringValue;
}
0 Likes
Message 3 of 26

klvnk
Collaborator
Collaborator

you expose utilities (or any other plugin) to mxs or the sdk via function publishing....  lots of examples in the sdk (it's literally brimming with them). If you just want to expose to other plugins and not mxs you do so via the interface system (from which function publishing is derived).

0 Likes
Message 4 of 26

klvnk
Collaborator
Collaborator

for a gup plugin it could be condensed to the following.....

 

 

 

// IMyInterface.h

#include "iFnPub.h"

#define MY_INTERFACE_ID		Interface_ID(0x4bc35422, 0x70000ea7)

class IMyInterface : public FPStaticInterface
{
public:

	enum functionID { kthefunction, knumfunctions };

	virtual float theFunction(float x) = 0;

};

inline IMyInterface* GetMyInterface() { return static_cast<IMyInterface*>(GetCOREInterface(MY_INTERFACE_ID));

// myutil.cpp

#include "IMyInterface.h"

// create the interface class

class MyUtilFPInterface: public IMyInterface
{
public:
	DECLARE_DESCRIPTOR(MyUtilFPInterface);

	BEGIN_FUNCTION_MAP
		FN_1(kthefunction, TYPE_FLOAT, theFunction)
	END_FUNCTION_MAP

	float theFunction() { return sin(x); }
	
};

// create the global instance of our interface 

static MyUtilFPInterface MyUtilFP(MY_INTERFACE_ID, _T("myutils"),
	IDS_UTIL_CLASS_NAME, NULL, FP_CORE,

	IMyInterface::kthefunction, _T("theFunction"), -1, TYPE_FLOAT, FP_NO_REDRAW, 1,
	_T("x"), 0, TYPE_FLOAT,
	p_end);

// then any other .cpp file its....

#include "IMyInterface.h"

IMyInterface* util = GetMyInterface();
float y = util->theFunction(x);

// and any mxs file

local y = myutils.theFunction(x);

 

 

 

you can hook into the original gup plugin by creating a static instance of it eg.....

 

 

 

static MyUtil gmyutil;

 

 

 

the call from that in the interface

 

 

 

class MyUtilFPInterface: public IMyInterface
{
public:
	DECLARE_DESCRIPTOR(MyUtilFPInterface);

	BEGIN_FUNCTION_MAP
		FN_1(kthefunction, TYPE_FLOAT, theFunction)
	END_FUNCTION_MAP

	float theFunction() { return gmyutil.sin(x); }
	
};

 

 

 

0 Likes
Message 5 of 26

istan
Advisor
Advisor

Thanks, but it did not answer my original question.

I don't want to add additional FP functions, as I already see all my utility plugin properties from MXS. They have been declared with paramblks and are already connected to dialog controls, so why should I add an extra interface again?

 

0 Likes
Message 6 of 26

klvnk
Collaborator
Collaborator

original question....

 

But how can I get access to these utitlity parameters from MXS or C++ ?

 

your response.....

 

I don't want to add additional FP functions, as I already have access to all my utility plugin properties from MXS

 

which is it ?

0 Likes
Message 7 of 26

omidt_gh
Enthusiast
Enthusiast

I answer the question pretty clear you get value from param block with the call:

value = pBlock->GetFloat(refno, GetCOREInterface()->GetTime());

this line will retrieve the float value from the Param block. not adding anything to it.

(you should know the reference number)
check my original answer, did you even check the answer?

0 Likes
Message 8 of 26

istan
Advisor
Advisor

@klvnk wrote:

I don't want to add additional FP functions, as I already have access to all my utility plugin properties from MXS

which is it ?


For simplification, let's stay at MXS only. If I enter:

showClass "myplug.*"

in MXS, I 'see' at least all the utility plugin properties, but I have no idea on how to get write-access to them.

With simple object based plugins with paramblocks you create an instance of it (a node) and have direct access to the parameters. But how's that working for a static util plugin?

 

0 Likes
Message 9 of 26

omidt_gh
Enthusiast
Enthusiast

Get to get parameters Set to set a parameters.

 

SimpleObject2::SetReference()
SimpleObject2::GetReference()

 

 

0 Likes
Message 10 of 26

istan
Advisor
Advisor

@omidt_gh wrote:

check my original answer, did you even check the answer?


Yes - I read. But I do neither have a "Mtl" nor a "Texmap":

std::string MaxToLuxMaps::getFloatByID(::Mtl* mat, ::Texmap* tex, int refno)

I have a utility plugin with paramblks which resides somewhere in the memory of 3dsmax.

 

0 Likes
Message 11 of 26

omidt_gh
Enthusiast
Enthusiast
SimpleObject2::SetReference()
SimpleObject2::GetReference()
0 Likes
Message 12 of 26

omidt_gh
Enthusiast
Enthusiast

Check these two classes and you will get your answer. do you have ever write c++ plugin.
I highly recommended looking at the basic training you will get all of your answers in 30 minutes.

0 Likes
Message 13 of 26

omidt_gh
Enthusiast
Enthusiast

it doesn't matter you want object/material/PF/map all of these are pointers to a object and you need exact same steps to get or set a parameters.

0 Likes
Message 14 of 26

omidt_gh
Enthusiast
Enthusiast

Try this one it will take just 30 minutes and you will learn how to set and get parameters and work with UI and viewport.
Also, you will find the source code available for every step.

https://help.autodesk.com/view/MAXDEV/2021/ENU/?guid=__developer_3ds_max_sdk___the_learning_path_htm... 

Screenshot 2021-03-22 204341.jpg

0 Likes
Message 15 of 26

istan
Advisor
Advisor

@omidt_gh wrote:

it doesn't matter you want object/material/PF/map all of these are pointers to a object and you need exact same steps to get or set a parameters.


Yes, I know. But how do I get the pointer to this volatile "utility object", which only exists when the panel was opened?

0 Likes
Message 16 of 26

omidt_gh
Enthusiast
Enthusiast

please check the basic tutorial. that's the very first line of the code.

First, you need the node

 

 

INode* node

 

 

That's what you should use and then see this node is a point to what object/Material, etc ....
Now you can get the object.

 

 

ObjectState os = node->EvalWorldState(t);

 

 

now use the object as a pointer and reach the other part.

And if you do not know how to access a node in the scene first you should access all objects like this:

 

 

INode* currNode = maxscene->GetChildNode(a);

 

 

a is an Integer and means the n'th object in the current scene.

and if you ask how to access the current scene you need to do it with:

 

 

INode* maxscene = GetCOREInterface7()->GetRootNode();

 

if you ask for selected object it will be always "&" in MXS as a pointer to current object.

 

You can just spend 30 minutes and check the very first basic tutorial you will understand all of them.
That's what you need to do, without that it is almost impossible to continue.

Take my advice and just spend 30 minutes of your time on it.

0 Likes
Message 17 of 26

klvnk
Collaborator
Collaborator

does your UtilityObj inherit from any other classes ? such as ReferenceMaker ? It might help if you posted the class code (just the outline should do)  

 

 

0 Likes
Message 18 of 26

istan
Advisor
Advisor

I took lesson5 and added a paramblk.

My own property sheet is missing from the vcxproj - so the max paths are missing there.

Build, start max with empty scene and enter 'showclass "lesson*.*" in maxscript listener.

It shows the paramblk properties, but how to access them now from MXS?

0 Likes
Message 19 of 26

omidt_gh
Enthusiast
Enthusiast

From C++ it's like this :

 

 

 

inf pbRefNo = 1;
Node->pblock->GetInt(pbRefNo ,0);

 

 

 

For MXS it will be like this :

 

 

 

int numrefs = refObj->NumRefs();
int paramblockRefNumber = 1;
for(int i=0; i < numrefs;i++)
{
 ReferenceTarget* ref = refObj->GetReference(i);
 if(ref->ClassID() == Class_ID(0x3bc31904, 0x67d74ec9))
 {
 Object* obj = dynamic_cast<Object*>(ref);
 if(obj)
 { 
 int value = obj->pblock->GetInt(paramblockRefNumber ,0);
 }
 }
}

 

 

you will need to change the refrence number for every single parameters you need to access, also be careful with GetInt/GetFloat/etc.

0 Likes
Message 20 of 26

omidt_gh
Enthusiast
Enthusiast

n you can the maxscript listener shows the parameters that variable you see is exactly you need.

just take a look at the code.

0 Likes