funny you should ask that… I’m not really sure it’s all a bit confusing
I was looking at the options with updating after copying map channels. defaultmapfaces (and other map channel polyop functions) uses this construct
EPoly* epi = NULL;
if (owner) {
epi = (EPoly*)((Animatable*)owner)->GetInterface(EPOLY_INTERFACE);
}
if (epi)
epi->LocalDataChanged ((channel<1) ? PART_VERTCOLOR : PART_TEXMAP);
return &ok;
which seems to have no effect when using defaultmapfaces :shrug: btw… (also update in mxs doesn’t always work either)
UpdateDisplayVertexColors & SetDisplayVertexColors have not effect in this case either.
for generic mesh changes you could try InvalidateGeomCache() maybe.
i’ve tried almost everyting… and couldn’t update anyway. maxscript UPDATE works fine, but i want to have complete deform function. i’ve tried to send notification messages… no luck. but i’m 100% sure it’s very easy i just don’t know what update and where to send
that’s what i do and it makes sense for me, but… doesn’t work:
bool updatePolyObject(INode* node)
{
Object* obj = Get_Object_Or_XRef_BaseObject(node->GetObjectRef());
BaseInterface* ip;
if ((ip = ((Animatable*)obj)->GetInterface(EPOLY_INTERFACE)) == NULL)
{
EPoly* ep = (EPoly*)ip;
ep->LocalDataChanged(PART_GEOM);
obj->NotifyDependents(FOREVER,PART_GEOM,REFMSG_CHANGE,NOTIFY_ALL,TRUE);
ep->RefreshScreen();
return true;
}
return false;
}
I think you may have a typo in there, you probably meant to say != NULL instead of == NULL.
Martijn
another puzzle…
update works as:
bool updatePolyObject(INode* node)
{
Object* obj = Get_Object_Or_XRef_BaseObject(node->GetObjectRef());
BaseInterface* ip;
if ((ip = ((Animatable*)obj)->GetInterface(EPOLY_INTERFACE)) != NULL)
{
EPoly* ep = (EPoly*)ip;
//ep->LocalDataChanged(PART_GEOM);
obj->NotifyDependents(FOREVER,PART_GEOM,REFMSG_CHANGE);
return true;
}
return false;
}
but it’s slower than call (update node) with mxs… LocalDataChanged is slower than NotifyDependents(FOREVER,PART_GEOM,REFMSG_CHANGE). what am i missing? what can mxs update do to make update faster?
but if i call notifydependents node partid:#geo with mxs after my sdk update it immediately updates the poly and redraws views
it is a bit of a catch all… maybe a selective pick of what you really need would help ? also InvalidateSurfaceUI call interacts with the editable poly UI which can’t help.
void EditPolyObject::LocalDataChanged (DWORD parts) {
bool sel = (parts & PART_SELECT) ? TRUE : FALSE;
bool topo = (parts & PART_TOPO) ? TRUE : FALSE;
bool geom = (parts & PART_GEOM) ? TRUE : FALSE;
bool vertCol = (parts & PART_VERTCOLOR) ? true : false;
InvalidateTempData (parts);
if (topo||sel||vertCol) InvalidateSurfaceUI ();
if (topo) {
SynchContArray(mm.numv);
// We need to make sure our named selection sets' sizes match our sizes:
selSet[0].SetSize (mm.numv);
selSet[1].SetSize (mm.nume);
selSet[2].SetSize (mm.numf);
mm.InvalidateTopoCache( false );
}
if (geom||topo) {
MNNormalSpec *pNorm = mm.GetSpecifiedNormals();
if (pNorm)
{
// If we have specified normals, we need to clear flags to indicate that they need to be updated.
// If we have a PART_TOPO change, the nonspecified normals need to be rebuilt.
// If we have a PART_GEOM change, the nonexplicit normals need to be recomputed.
if (topo) pNorm->ClearFlag (MNNORMAL_NORMALS_BUILT);
else pNorm->ClearFlag (MNNORMAL_NORMALS_COMPUTED);
}
mm.InvalidateGeomCache ();
if (topo)
mm.freeRVerts ();
} else if (vertCol) mm.InvalidateHardwareMesh ();
if (sel) {
InvalidateNumberSelected ();
UpdateNamedSelDropDown ();
}
subdivValid.SetEmpty ();
if (killRefmsg.DistributeRefmsg())
NotifyDependents(FOREVER, parts, REFMSG_CHANGE);
}
void EditPolyObject::InvalidateTempData (PartID parts) {
if (!tempMove) {
if (tempData) tempData->Invalidate (parts);
if (parts & (PART_TOPO|PART_GEOM|PART_SELECT|PART_SUBSEL_TYPE))
{
//only invalidate the cache when it's actually being used.
//invalidating the soft selection cache causes the subdivided mesh to be rebuilt if it's on
int useSoftSel = 0;
pblock->GetValue (ep_ss_use, GetCOREInterface()->GetTime(), useSoftSel, arValid);
if ( useSoftSel )
{
InvalidateSoftSelectionCache ();
}
}
}
// we NEVER call InvalidateTopoCache, since that trashes the edge list.
if (parts & PART_TOPO)
{
mm.ClearFlag(MN_MESH_PARTIALCACHEINVALID);
mm.SetFlag(MN_CACHEINVALID);
mm.freeRVerts();
}
if (parts & PART_GEOM) mm.InvalidateGeomCache ();
if ((parts & PART_SELECT) && tempData) tempData->freeBevelInfo();
// Any change in mesh should invalidate the preview.
if (EpPreviewOn()) EpPreviewInvalidate ();
}
i have no idea why this useful function is not exposed for MXS:
def_visible_primitive (formatRenderTime, "formatRenderTime");
Value* formatRenderTime_cf(Value** arg_list, int count)
{
check_arg_count_with_keys(all, 1, count);
int time = arg_list[0]->to_int();
BOOL hundredths = key_arg_or_default(all, &false_value)->to_bool();
MSTR str;
MAXScript_interface11->FormatRenderTime(time, str, hundredths);
return new String(str);
}
i can’t build this simple function:
def_visible_primitive(getControlHWND, "getControlHWND");
Value* getControlHWND_cf(Value **arg_list, int count)
{
check_arg_count(getControlHWND, 1, count);
if (is_rolloutcontrol(arg_list[0]))
{
HWND hwnd = ((RolloutControl*)arg_list[0])->GetHWND();
return IntegerPtr::intern((INT_PTR)hwnd);
}
return &undefined;
}
i have this error message:
error LNK2019: unresolved external symbol “public: struct HWND__ * cdecl RolloutControl::GetHWND(void)” (?GetHWND@RolloutControl@@QEAAPEAUHWND@@XZ) referenced in function “class Value * __cdecl getControlHWND_cf(class Value * *,int)”
as i understand the compiler can’t find some lib file. but i have no idea which one missed. Any ideas?
thanks
don’t think you can use that as it’s not part of the “interface” e.g. it’s not virtual… In the rolloutcontrols I’ve look at (mxsagni project in samples) and the one I attempted to implement the hwnd is defined in the child class with no imperative to implement a GetHWND() function.
though i maybe wrong and very often are the libraries are listed here
another edit doesn’t link in one of my projects with a working custom rollout control so it should have all the necessary linkages. :shrug:
this is from header “rollouts.h”
visible_class (RolloutControl)
class RolloutControl : public Value, public ReferenceMaker
{
public:
Value* name;
Value* caption;
Value* init_caption;
<...>
// added for r11
HWND GetHWND();
};
it’s public. it’s visible… why is it not working?
i found a workaround:
def_visible_primitive(getControlHWND, "getControlHWND");
Value* getControlHWND_cf(Value **arg_list, int count)
{
check_arg_count_with_keys(getControlHWND, 1, count);
int id = key_arg_or_default(id,Integer::intern(0))->to_int();
if (is_rolloutcontrol(arg_list[0]))
{
RolloutControl *control = (RolloutControl*)arg_list[0];
HWND hwnd = GetDlgItem(control->parent_rollout->page, control->control_ID + id);
return IntegerPtr::intern((INT_PTR)hwnd);
}
return &undefined;
}
actually the new way is power powerful. using optional ID argument it can return HWND for a ‘multi-controls’ control (like a spinner)
thanks, Klunk for this set of very useful functions… the only problem I have is to get MNMesh updated. as you see i’ve modifies the function above to return the number of nspec faces. the function returns 0 all the time, but the right number was allocated and built! what do we have to update the return the right number?
thanks