how does it get #mapcoords from say a standard box object ? especially in pre pblock2 versions…

it’s not listed in the get parameter name function…

TSTR BoxObject::GetParameterName(int pbIndex) 
	switch (pbIndex) {
		case PB_LENGTH: return TSTR(GetString(IDS_RB_LENGTH));
		case PB_WIDTH:  return TSTR(GetString(IDS_RB_WIDTH));
		case PB_HEIGHT: return TSTR(GetString(IDS_RB_HEIGHT));
		case PB_WSEGS:  return TSTR(GetString(IDS_RB_WSEGS));
		case PB_LSEGS:  return TSTR(GetString(IDS_RB_LSEGS));
		case PB_HSEGS:  return TSTR(GetString(IDS_RB_HSEGS));
		default: return TSTR(_T(""));

I don’t see any related interfaces it could come from as is the case with #realWorldMapSize and IParamBlock doesn’t support local param names (even the pblock2 version it’s questionable if it’s retrieved from the pb as its defined “mapCoords” there :roll_eyes:

would love to see the source code for getproperty setproperty and getpropnames etc :slight_smile:
so i can see whats what and what i’m missing !


These functions are virtual functions… You, as a developer, can return whatever you like :wink:


you can get/set it by name:

template<typename T>
inline bool IParamBlock2::SetValueByName(const MCHAR* const paramName, const T& value, const TimeValue t, const int tabIndex)

template<typename T>
inline bool IParamBlock2::GetValueByName(const MCHAR* const paramName, const TimeValue t, T& value, Interval& validity, const int tabIndex)


needs to work in IParamBlock not just IParamBlock2, besides thats “mapCoords” not “mapcoords”


the SDK say…

// When a client of a param block receives the \ref REFMSG_GET_PARAM_NAME
// message, the partID field is set to point at one of these structures.
// The client should fill in the parameter name.
/*! \sa  Class ParamDimension.
\par Description:
This class is used to hold a parameter name. When a client of a parameter block
receives the \ref REFMSG_GET_PARAM_NAME message, the partID field is set to
point at one of these structures. The client should fill in the parameter name.
\par Data Members:
<b>MSTR name;</b>\n\n
Assign the parameter name to this variable.\n\n
<b>int index;</b>\n\n
Index of the parameter in the parameter block.  */
class GetParamName: public MaxHeapOperators {
		MSTR name;
		int index;
		/*! \remarks Constructor. */
		GetParamName(MSTR n,int i) { name=n;index=i; }

seems to be the only way to get the name


Yeah Simple object does support this…

			GetParamName *gpn = (GetParamName*)partID;
			gpn->name = GetParameterName(gpn->index);			
			return REF_HALT; 

calling the function in the OP which does’nt include “mapcoords”. There must be an interface somewhere i’m missing or it’s something to do with HasUVW in BaseObject :confused:

it’s quite funny that a few objects in the extended primitives do have mapcoords in their GetParameterName functions… obviously didn’t get the memo!

it’s also quite weird that the names are spat out from getpropnames in an order that is completely at odds with parameter indices :confused:


NotifyRefChanged is from ReferenceMaker… It’s the base for almost everything

Just very interesting for myself. I’d like to give it a try…


my current thinking it’s just hard coded for all objects with pb1 and autodicks just assumes all third party stuff will be pb2


I tested the GetParamName with…

INode* node = arg_list[knode]->to_node();
	Object* obj = node->GetObjectRef();

	GetParamName gpn(TSTR(_T("")), arg_list[kindex]->to_int());

	IParamBlock* pb = static_cast<IParamBlock*>(obj->GetParamBlock());

it works but the names are different and it’s not used by the MXS GetPropNames as I recompiled the prim proj with some modifications and BoxObject
TSTR GetParameterName(int pbIndex);

isn’t called AFAICS also they come out in a different order and mapcoords is still missing :confused:


Are you sure this is the correct paramblock? There can be more than one, and GetParamBlock() is not the same as GetParamBlock(0).


yeah, it’s was tested in max 2010 and box objects don’t have iparamblock2 so don’t support
iparamblock2* Animatable::GetParamBlock(int i)


I certainly don’t remember how many paramblocks the box object has in 2010, but I think more than one. Doesn’t a paramblock in 2010 have a getparamblock method by index?


it’s a simpleobject with just one

class SimpleObject : public GeomObject {
		IParamBlock *pblock;


As I said, you can’t trust the GetPropNames method because it’s up to the developer to make that list (and order it) right. So the list as a whole does not correspond to the actual list of parameters (subanims). For example, I don’t care about the correct order and the complete list for my Values. :upside_down_face:

Also I can confirm …


the method returns some names, but it might be wrong with published names, their order and the number of parameters. I guess it’s because of missplacing subanims and block params. There has to be a method which corresponds subanim id and param index… but there’s the mess too.

How is about to make a MAXWrapper and ask the MAXWrapper the property by name (_get_property) ?
But you have to mess with the param’s SDK type youself…


Solved one of the quanderies… the conversion to #name throws up some interesting results. illustrated by…

"ABC" as name
"mapCoords" as name 

if the name is already in the hash table it uses that existing value hence the decapitalization on only some of the properties when using getpropnames on objects using IParamBlock2 :sunny:

I decided on a hard coded lookup map initialized by some xml for any primitives not IParamBlock2 enabled


I never had any problems with IParamBlock2… but you’ve asked about IParamBlock


if you look in “corenames.inl” you would see two names: #mapCoords amd #mapcoords … this is why I do lowercase comparing for all names (subanim, params, props, etc.)


it’s not an issue with IParamBlock2 per se…

p = plane()
getpropnames p

produces the out put

#(...... #renderScale, #mapcoords, .....)

but the actual names are…
“renderScale” and “mapCoords”

it’s the conversion from string to name throwing up a few oddities

this is why I do lowercase comparing for all names

I think the conversion to name does the same when it searches the hashtable to see if the name is already registered hence it throwing up the lower case version :slight_smile:


It throws not a low case but the first put in hashtable.
Using hashed names instead of string helps to save maxscript memory. Similar hashtable also is used for global, function and structure names…

Technically you could go in there and fix your favorite name to your preferred spelling, like “mApcOOrds” :grin:


it quite interesting that getpropnames (get & set properties) goes through ClassDesc (via DllDir) not the node (other than providing the class id’s) when dealing with pb2 based objects.

I decided going via names was too much of a ball ache when just using id’s was much less painful :smiley: