Update Issue with ObjectData
-
On 31/01/2013 at 01:14, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R14
Platform: Windows ;
Language(s) :---------
Hey guys,I trying to do the following:
I got an objectdata generator plugin which takes a spline and generate maybe an extrude nurbs with that spline.
But here special is, that the spline should not be under the generator, it should be the previous or parent.If I use spline = op->GetPred() it works but the editor does not update correct not until I click in the editor view.
If I use spline = op->GetUp() it does not work, c4d crash.
If I use spline = op->GetDown() all is fine.Check dirty of spline does not work, but you will see the effect if you toggle xray or change any other data of the generator (color, name...).
#include "c4d.h" #define ID_PLUGIN_TESTOBJECT 12345678 class TestObject : public ObjectData { INSTANCEOF(TestObject, ObjectData) public: virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh); static NodeData* Alloc(void) { return gNew TestObject; } }; BaseObject* TestObject::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) { BaseObject *spline = op->GetPred(); //BaseObject *spline = op->GetUp(); //BaseObject *spline = op->GetDown(); if (!spline || (spline->GetInfo() & OBJECT_ISSPLINE) != OBJECT_ISSPLINE) return NULL; // check cache for validity and check master object for changes Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS_DATA); // check spline for changes - does not work dirty |= spline->IsDirty(DIRTYFLAGS_DATA) || spline->IsDirty(DIRTYFLAGS_MATRIX) || spline->IsDirty(DIRTYFLAGS_CACHE); // if no change has been detected, return original cache if (!dirty) return op->GetCache(hh); BaseObject *obj = BaseObject::Alloc(Oextrude); BaseObject *splineClone = (BaseObject* ) spline->GetClone(COPYFLAGS_0, NULL); splineClone->InsertUnder(obj); return obj; } Bool RegisterTestObject(void) { return RegisterObjectPlugin(ID_PLUGIN_TESTOBJECT, "TestObject", OBJECT_GENERATOR, TestObject::Alloc, "", NULL, 0); }
-
On 31/01/2013 at 07:59, xxxxxxxx wrote:
Hi Toni,
With op->GetUp() it crashes because you call spline->GetClone() and both the spline and the generator itself are copied.
To only copy the spline, call spline->GetClone(COPYFLAGS_NO_HIERARCHY, NULL).Generators aren't modifiers: you can't take a parent or sibling object as input object(s).
A generator object plugin can be registered with the OBJECT_INPUT flag but this will only work in the pipeline of CINEMA if you take the subobject(s) as input.Also checking the dirty flag works better with C4DAtom::GetDirty():
ULONG dirty = spline->GetDirty(DIRTYFLAGS_DATA|DIRTYFLAGS_MATRIX); if (dirty==this->dirtyCount) return op->GetCache(hh);
dirtyCount is a member of the generator and caches the last dirty count for the comparison.
-
On 31/01/2013 at 08:18, xxxxxxxx wrote:
Thank you for your replay.
You are right, the op->GetUp() was a silly idea. o.OI figured out that spline->GetClone() is my problem. If I use a Generator with a Link Attribute (Linked to a spline) and use spline->GetClone(), the same "buggy" update happen:
GetVirtualObjects is called, but not until I click in the 3d view the editor is redrawn.
If I clone the spline manual (rewriting points and tangents) it works better.
Would it be save?
SplineObject* CopySpline(SplineObject *spline) { LONG pcnt = spline->GetPointCount(); LONG scnt = spline->GetSegmentCount(); LONG tcnt = spline->GetTangentCount(); SplineObject *newSpline = SplineObject::Alloc(pcnt, spline->GetInterpolationType()); newSpline->ResizeObject(pcnt, scnt); newSpline->SetData(spline->GetData(), FALSE); // Copy Points const Vector *points = spline->GetPointR(); Vector *newPoints = newSpline->GetPointW(); for (LONG i = 0; i < pcnt; i++) { newPoints[i] = points[i]; } // Copy Tangents const Tangent *tangents = spline->GetTangentR(); Tangent *newTangents = newSpline->GetTangentW(); for (LONG i = 0; i < tcnt; i++) { newTangents[i] = tangents[i]; } const Segment *segment = spline->GetSegmentR(); Segment *newSegment = newSpline->GetSegmentW(); for (LONG i = 0; i < scnt; i++) { newSegment[i] = segment[i]; } newSpline->Message(MSG_UPDATE); return newSpline; }
-
On 01/02/2013 at 05:26, xxxxxxxx wrote:
Yes, it's safe if you copy manually all the spline data.