hello
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)
{
maxon::BaseArray<BaseObject*> objArray;
while (obj != nullptr)
{
objArray.Append(obj);
// we can append the array from another array.
objArray.Append(HierarchyIterator(obj->GetDown()));
obj = obj->GetNext();
}
return objArray;
}
BaseObject* PC11572::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)
{
if (op == nullptr || hh == nullptr)
{
return BaseObject::Alloc(Onull);
}
BaseObject* firstChild = op->GetDown();
if (firstChild == nullptr)
{
return 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);
trans->Translate(true);
if (!res)
{
return BaseObject::Alloc(Onull);;
}
if (dirty)
{
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)
continue;
// 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;
}
}
return newSpline;
}
else
{
DiagnosticOutput("There nothing to do");
// returning res because GetAndCheckHierarchyClone return cache if not dirty
return res;
}
return BaseObject::Alloc(Onull);
}
Cheers
Manuel