there are some another things not exposed to mxs:
class ISnap : public FPInterfaceDesc
{
public:
static const Interface_ID id;
enum FunctionIDs
{
_SnapAngle,
_SnapPercent,
_GetSnapAngle,
_SetSnapAngle,
_GetSnapPercent,
_SetSnapPercent,
_ASnapStatus,
_SetASnapStatus,
_PSnapStatus,
_SetPSnapStatus,
_ToggleASnap,
_TogglePSnap,
};
ISnap() : FPInterfaceDesc(id, _M("ISnap"), 0, NULL, FP_CORE, end)
{
AppendFunction(
_SnapAngle,_M("SnapAngle"), 0, TYPE_FLOAT, 0, 3,
_M("angle"), 0, TYPE_FLOAT,
_M("fast"), 0 , TYPE_BOOL, f_keyArgDefault, TRUE,
_M("force"), 0 , TYPE_BOOL, f_keyArgDefault, FALSE,
end);
AppendFunction(
_SnapPercent,_M("SnapPercent"), 0, TYPE_FLOAT, 0, 1,
_M("percent"), 0, TYPE_FLOAT,
end);
AppendFunction(
_GetSnapAngle,_M("GetSnapAngle"), 0, TYPE_FLOAT, 0, 0,
end);
AppendFunction(
_SetSnapAngle,_M("SetSnapAngle"), 0, TYPE_VALUE, 0, 1,
_M("val"), 0, TYPE_FLOAT,
end);
AppendFunction(
_GetSnapPercent,_M("GetSnapPercent"), 0, TYPE_FLOAT, 0, 0,
end);
AppendFunction(
_SetSnapPercent,_M("SetSnapPercent"), 0, TYPE_VALUE, 0, 1,
_M("val"), 0, TYPE_FLOAT,
end);
AppendFunction(
_ASnapStatus,_M("GetAngleSnapStatus"), 0, TYPE_bool, 0, 0,
end);
AppendFunction(
_SetASnapStatus,_M("SetAngleSnapStatus"), 0, TYPE_bool, 0, 1,
_M("val"), 0, TYPE_bool,
end);
AppendFunction(
_PSnapStatus,_M("GetPercentSnapStatus"), 0, TYPE_bool, 0, 0,
end);
AppendFunction(
_SetPSnapStatus,_M("SetPercentSnapStatus"), 0, TYPE_bool, 0, 1,
_M("val"), 0, TYPE_bool,
end);
AppendFunction(
_ToggleASnap,_M("ToggleAngleSnap"), 0, TYPE_bool, 0, 0,
end);
AppendFunction(
_TogglePSnap,_M("TogglePercentSnap"), 0, TYPE_bool, 0, 0,
end);
}
static float SnapAngle(float angle, BOOL fast = TRUE, BOOL force = FALSE) {
return GetCOREInterface()->SnapAngle(angle, fast, force);
}
static float SnapPercent(float percent) {
return GetCOREInterface()->SnapPercent(percent);
}
static float GetSnapAngle() {
return MAXScript_interface7->GetSnapAngle();
}
static Value* SetSnapAngle(float val) {
MAXScript_interface7->SetSnapAngle(val);
return &ok;
}
static float GetSnapPercent() {
return MAXScript_interface7->GetSnapPercent();
}
static Value* SetSnapPercent(float val) {
MAXScript_interface7->SetSnapPercent(val);
return &ok;
}
static int GetAngleSnapStatus() {
return MAXScript_interface7->ASnapStatus();
}
static bool SetAngleSnapStatus(bool val) {
bool prev = (MAXScript_interface7->ASnapStatus()) ? true : false;
if (prev != val) MAXScript_interface7->ToggleASnap();
return val;
}
static int GetPercentSnapStatus() {
return MAXScript_interface7->PSnapStatus();
}
static bool SetPercentSnapStatus(bool val) {
bool prev = (MAXScript_interface7->PSnapStatus()) ? true : false;
if (prev != val) MAXScript_interface7->TogglePSnap();
return val;
}
static bool ToggleAngleSnap() {
MAXScript_interface7->ToggleASnap();
return MAXScript_interface7->ASnapStatus() != 0;
}
static bool TogglePercentSnap() {
MAXScript_interface7->TogglePSnap();
return MAXScript_interface7->PSnapStatus() != 0;
}
BEGIN_FUNCTION_MAP
FN_3(_SnapAngle, TYPE_FLOAT, SnapAngle, TYPE_FLOAT, TYPE_BOOL, TYPE_BOOL)
FN_1(_SnapPercent, TYPE_FLOAT, SnapPercent, TYPE_FLOAT)
FN_0(_GetSnapAngle, TYPE_FLOAT, GetSnapAngle)
FN_1(_SetSnapAngle, TYPE_VALUE, SetSnapAngle, TYPE_FLOAT)
FN_0(_GetSnapPercent, TYPE_FLOAT, GetSnapPercent)
FN_1(_SetSnapPercent, TYPE_VALUE, SetSnapPercent, TYPE_FLOAT)
FN_0(_ASnapStatus, TYPE_bool, GetAngleSnapStatus)
FN_1(_SetASnapStatus, TYPE_bool, SetAngleSnapStatus, TYPE_bool)
FN_0(_PSnapStatus, TYPE_bool, GetPercentSnapStatus)
FN_1(_SetPSnapStatus, TYPE_bool, SetPercentSnapStatus, TYPE_bool)
FN_0(_ToggleASnap, TYPE_bool, ToggleAngleSnap)
FN_0(_TogglePSnap, TYPE_bool, TogglePercentSnap)
END_FUNCTION_MAP
};
const Interface_ID ISnap::id = Interface_ID(0x02feb1967, 0x790a7898);
static ISnap isnapInterface;
i can’t find any sample how to append property to FPInterfaceDesc.
there is the AppendProperty method but how to define the property SET and GET methods? thanks in advance…
hey denis I’m not sure you really need those member functions to be declared as static. static member functions are used (for the most part) if you need to call a function on a class that hasn’t been instanced e.g. for getting and setting static class members before the class is initiated. You could try removing
static ISnap isnapInterface;
and see if it still works I suppose.
theres examples of the property and enumeration setting in maxsdk\help\3dsMaxSDK.chm under function publishing :: property Accessors and
function publishing :: symbolic Enumerations
if you didn’t know another technique you can use in function publishing is to pass return values as a pointer even single int sized values because if you return NULL max will auto convert it to undefined in mxs
your PathConfigMgr example with a property called radius
class PathConfigMgr : public FPInterfaceDesc
{
public:
static const Interface_ID id;
enum FunctionIDs
{
_getresolveunc,_setresolveunc,_getresolvetorelative,_setresolvetorelative, _getRadius, _setRadius
};
PathConfigMgr() : FPInterfaceDesc(id, _M("PathConfigMgr"), 0, NULL, FP_CORE, end)
{
AppendFunction(
_getresolveunc, _M("GetResolveUNC"), 0, TYPE_BOOL, 0, 0,
end);
AppendFunction(
_setresolveunc, _M("SetResolveUNC"), 0, TYPE_BOOL, 0, 1,
_M("flag"), 0, TYPE_BOOL,
end);
AppendFunction(
_getresolvetorelative, _M("GetResolveToRelative"), 0, TYPE_BOOL, 0, 0,
end);
AppendFunction(
_setresolvetorelative, _M("SetResolveToRelative"), 0, TYPE_BOOL, 0, 1,
_M("flag"), 0, TYPE_BOOL,
end);
AppendProperty(_getRadius, _setRadius, _T("radius"), IDS_RADIUS,
TYPE_FLOAT, f_range, 0.0, 10000.0, end);
}
float r;
float GetRadius() { return r; }
void SetRadius(float radius) { r = radius; }
bool GetResolveUNC()
{
return IPathConfigMgr::GetPathConfigMgr()->GetResolveUNC();
}
bool SetResolveUNC(BOOL flag)
{
bool prev = GetResolveUNC();
IPathConfigMgr::GetPathConfigMgr()->SetResolveUNC(flag == TRUE);
return prev;
}
bool GetResolveToRelative()
{
return IPathConfigMgr::GetPathConfigMgr()->GetResolveToRelative();
}
bool SetResolveToRelative(BOOL flag)
{
bool prev = GetResolveToRelative();
IPathConfigMgr::GetPathConfigMgr()->SetResolveToRelative(flag == TRUE);
return prev;
}
BEGIN_FUNCTION_MAP
FN_0(_getresolveunc, TYPE_BOOL, GetResolveUNC)
FN_1(_setresolveunc, TYPE_BOOL, SetResolveUNC, TYPE_BOOL)
FN_0(_getresolvetorelative, TYPE_BOOL, GetResolveToRelative)
FN_1(_setresolvetorelative, TYPE_BOOL, SetResolveToRelative, TYPE_BOOL)
PROP_FNS(_getRadius, GetRadius, _setRadius, SetRadius, TYPE_FLOAT);
END_FUNCTION_MAP
};
const Interface_ID PathConfigMgr::id = Interface_ID(0x62174bc6, 0x790c7394);
static PathConfigMgr PathConfigMgrInterface;
showinterface PathConfigMgr
Interface: PathConfigMgr
Properties:
.radius : float : Read|Write|Validated by Range: 0.0 to 10000.0
Methods:
<boolean>GetResolveUNC()
<boolean>SetResolveUNC flag
<boolean>GetResolveToRelative()
<boolean>SetResolveToRelative flag
Actions:
OK
also if you add something like
r(100.0f)
to the constructor initializer list then radius will 100.0f at startup
thanks… but i’m still not clear about the syntax.
good now you know how we feel looking at some of your mxs stuff
now it’s much clearer
thanks!
as you understand i’m rewriting my mxs extension libraries to the interface style. which is pretty cool i found.
function publishing’s more c++ like interface is nicer to deal with than the macro heavy exposure method and has nice ecapsulation (especially with your way of doing it) but the exposure method does have a 2:1 advantage in speed critical routines going for it !
claude666,
what is IDS_RADIUS in your sample and where i have to define it?
edit… never mind. i’ve got it
here is fixed and simplified the ISnap interface by using {get, set} status properties.
class ISnap : public FPInterfaceDesc
{
public:
static const Interface_ID id;
enum FunctionIDs
{
_SnapAngle,
_SnapPercent,
_GetSnapAngle,
_SetSnapAngle,
_GetSnapPercent,
_SetSnapPercent,
_getAStatus, _setAStatus,
_getPStatus, _setPStatus,
};
#define IDS_ASTATUS 0
#define IDS_PSTATUS 1
ISnap() : FPInterfaceDesc(id, _M("ISnap"), 0, NULL, FP_CORE, end)
{
AppendFunction(
_SnapAngle,_M("SnapAngle"), 0, TYPE_FLOAT, 0, 3,
_M("angle"), 0, TYPE_FLOAT,
_M("fast"), 0 , TYPE_BOOL, f_keyArgDefault, TRUE,
_M("force"), 0 , TYPE_BOOL, f_keyArgDefault, FALSE,
end);
AppendFunction(
_SnapPercent,_M("SnapPercent"), 0, TYPE_FLOAT, 0, 1,
_M("percent"), 0, TYPE_FLOAT,
end);
AppendFunction(
_GetSnapAngle,_M("GetSnapAngle"), 0, TYPE_FLOAT, 0, 0,
end);
AppendFunction(
_SetSnapAngle,_M("SetSnapAngle"), 0, TYPE_VALUE, 0, 1,
_M("val"), 0, TYPE_FLOAT,
end);
AppendFunction(
_GetSnapPercent,_M("GetSnapPercent"), 0, TYPE_FLOAT, 0, 0,
end);
AppendFunction(
_SetSnapPercent,_M("SetSnapPercent"), 0, TYPE_VALUE, 0, 1,
_M("val"), 0, TYPE_FLOAT,
end);
AppendProperty(_getAStatus, _setAStatus, _T("AngleSnapStatus"), IDS_ASTATUS, TYPE_bool, end);
AppendProperty(_getPStatus, _setPStatus, _T("PercentSnapStatus"), IDS_PSTATUS, TYPE_bool, end);
}
bool aStatus;
bool getAStatus() { return MAXScript_interface7->ASnapStatus() != 0; }
void setAStatus(bool val) { aStatus = SetAngleSnapStatus(val); }
bool pStatus;
bool getPStatus() { return MAXScript_interface7->PSnapStatus() != 0; }
void setPStatus(bool val) { aStatus = SetPercentSnapStatus(val); }
float SnapAngle(float angle, BOOL fast = TRUE, BOOL force = FALSE) {
return GetCOREInterface()->SnapAngle(angle, fast, force);
}
float SnapPercent(float percent) {
return GetCOREInterface()->SnapPercent(percent);
}
float GetSnapAngle() {
return MAXScript_interface7->GetSnapAngle();
}
Value* SetSnapAngle(float val) {
MAXScript_interface7->SetSnapAngle(val);
return &ok;
}
float GetSnapPercent() {
return MAXScript_interface7->GetSnapPercent();
}
Value* SetSnapPercent(float val) {
MAXScript_interface7->SetSnapPercent(val);
return &ok;
}
bool SetAngleSnapStatus(bool val) {
bool prev = (MAXScript_interface7->ASnapStatus()) ? true : false;
if (prev != val) MAXScript_interface7->ToggleASnap();
return val;
}
bool SetPercentSnapStatus(bool val) {
bool prev = (MAXScript_interface7->PSnapStatus()) ? true : false;
if (prev != val) MAXScript_interface7->TogglePSnap();
return val;
}
BEGIN_FUNCTION_MAP
FN_3(_SnapAngle, TYPE_FLOAT, SnapAngle, TYPE_FLOAT, TYPE_BOOL, TYPE_BOOL)
FN_1(_SnapPercent, TYPE_FLOAT, SnapPercent, TYPE_FLOAT)
FN_0(_GetSnapAngle, TYPE_FLOAT, GetSnapAngle)
FN_1(_SetSnapAngle, TYPE_VALUE, SetSnapAngle, TYPE_FLOAT)
FN_0(_GetSnapPercent, TYPE_FLOAT, GetSnapPercent)
FN_1(_SetSnapPercent, TYPE_VALUE, SetSnapPercent, TYPE_FLOAT)
PROP_FNS(_getAStatus, getAStatus, _setAStatus, setAStatus, TYPE_bool);
PROP_FNS(_getPStatus, getPStatus, _setPStatus, setPStatus, TYPE_bool);
END_FUNCTION_MAP
};
const Interface_ID ISnap::id = Interface_ID(0x02feb1967, 0x790a7898);
static ISnap isnapInterface;
it’s now:
Interface: ISnap
Properties:
.AngleSnapStatus : bool : Read|Write
.PercentSnapStatus : bool : Read|Write
Methods:
<float>SnapAngle <float>angle fast:<boolean> force:<boolean>
fast default value: true
force default value: false
<float>SnapPercent <float>percent
<float>GetSnapAngle()
<value>SetSnapAngle <float>val
<float>GetSnapPercent()
<value>SetSnapPercent <float>val
Actions:
claude666, thanks again.