I'm working on a plugin were I want to take an input child object spline and use its points as a basis for an output. I'm able to get when the object is dirty reliably and only update when I have to. But when I have an object like an Oinstance or an Oconnector, I'm not getting a dirty message from them if the object inputting into them has been updated.
Aside from manually checking the object type and checking INSTANCEOBJECT_LINK and CONNECTOBJECT_LINK respectively I can't figure out a way to get if they have actually updated and therefore I have to update.
Is there way to get the dependence list for a given object so I can manually check it? Since the linked connect/instance isn't being marked as dirty I don't know another approach to use. Or is there a better way to know when an input into one of those objects has updated?
I was trying to do what you want for your project and maybe i found something. (pick a hierarchy and return a spline)
Seems that you can use GetAndCheckHierarchyClone()
This function check if something have changed. Return A hierarchy of PolygonObject or SplineObject so you don't have to use makeeditable or get cache or what ever.
I didn't thought immediately but you can add several flag like so HIERARCHYCLONEFLAGS::ASPOLY | HIERARCHYCLONEFLAGS::ASSPLINE
This function return the cache if nothing have changed.
I've created a function to create a BaseArray of all objects but you can pick your own solution.
maxon::BaseArray<BaseObject*> PC11572::HierarchyIterator(BaseObject* obj)
while (obj != nullptr)
// we can append the array from another array.
obj = obj->GetNext();
BaseObject* PC11572::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)
if (op == nullptr || hh == nullptr)
BaseObject* firstChild = op->GetDown();
if (firstChild == nullptr)
BaseObject* res = nullptr;
Bool dirty = false;
AutoAlloc <AliasTrans> trans;
if (!trans) return nullptr;
if (!trans->Init(hh->GetDocument())) return nullptr;
res = op->GetAndCheckHierarchyClone(hh, firstChild, HIERARCHYCLONEFLAGS::ASPOLY | HIERARCHYCLONEFLAGS::ASSPLINE, &dirty, trans, true);
DiagnosticOutput("This is dirty Create a new spline");
// Gets an array of every object
maxon::BaseArray<BaseObject*> myList = HierarchyIterator(res);
// Creates a new spline
SplineObject* newSpline = SplineObject::Alloc(0, SPLINETYPE::LINEAR);
// Gets the revers Matrix (to go from global space to local space
const Matrix invOpMg = ~op->GetMg();
maxon::Int32 lastPoint = 0;
for (auto &child : myList)
// The object should already be Opoint or Ospline but extra check doesn't hurt
if (child->IsInstanceOf(Opoint) || child->IsInstanceOf(Ospline))
const maxon::Int32 pcnt = ToPoly(child)->GetPointCount();
const Vector* childPadr = ToPoly(child)->GetPointR();
// Don't waste time if there's no point to add
if (pcnt == 0)
// Resizes the spline without changing the Segment number (one segment should be created for each object / each spline segment)
newSpline->ResizeObject(lastPoint + pcnt, 1);
// Gets write access to the points
Vector* padr = newSpline->GetPointW();
// Gets the first element in the writable segments array
Segment* seg = newSpline->GetSegmentW();
// Changes the number of points in that segment
seg->cnt = lastPoint + pcnt;
// Gets the matrix of the child to go from local to global
const Matrix childMg = child->GetMg();
for (maxon::Int32 i = lastPoint, j = 0 ; i < lastPoint + pcnt; i++, j++)
// Updates the points position from child, by going from local to global to local.
padr[i] = invOpMg * (childMg * childPadr[j]);
// Updates last points index so the next object will go behind.
lastPoint += pcnt;
DiagnosticOutput("There nothing to do");
// returning res because GetAndCheckHierarchyClone return cache if not dirty
this topics will be considered as resolved if you have nothing to add.