Thank you for the reply, @ferdinand,
-
Thanks for the
PrerollToTime()
function! I didn't know that I need toExecutePasses()
for each frame until thelastFrame
.I'm writing a tag plugin that has a parameter which is a link to an existing vertex color tag, and a parameter to allow user specify a frame number. These two parameters work together, so the plugin will get the data from the vertex color tag at the specific frame, and use the data to do the rendering across all frames.
-
1.1 Because the tag plugin depends the linked vertex color tag, so whenever there is a change in the vertex color tag, the plugin needs to update its internal data based on the updated vertex color tag. Currently, I do this in the tag plugin's Execute() function. The tag plugin remembers the vertex color tag's pointer (initialized as
nullptr
) and dirty checksum (byC4DAtom::GetDirty()
, and initialized as 0). SoExecute()
checks if the vertex color tag read from the link parameter changes or the vertex color tag's dirty checksum changes, if it changes, the vertex color tag's data at the specified frame will be read again.However, I found
ExecutePasses()
called inPrerollToTime()
triggers the tag plugin'sExecute()
function (I think this is the cloned tag in the cloned document), andExecute()
function tries to read the linked vertex color tag at the speficied frame again, soPrerollToTime()
->ExecutePasses()
is called again, and triggers a new cloned tag in a new cloned document to run itsExecute()
, and so on.This makes me wonder if I'm not using the correct way to check if the linked vertex color tag's change. Could you please help find out what's C4D's recommended way to handle such case?
-
1.2 According to the sample code
PrerollToTime()
, thelastFrame
(the target frame) must not be earlier than the current scene's time. This means if the scene's current time is later than the frame number (say, user slides the timeline to frame 10, but the frame number parameter is set to 5), there will be no way to get the desired data from the vertex color tag, right? How does C4d handle this kind of situation? Or there is no such situation at all in native C4d?
-
-
To get the same tag from the cloned scene, I could use code like below, but I am wondering if there is an existing API to do this, as I think this is a basic need.
BaseObject* getObjectByMarker(const BaseDocument& doc, const GeMarker& objMarker, BaseObject* start = nullptr)
{
for (BaseObject* obj = start ? start : doc.GetFirstObject(); obj != nullptr; obj = obj->GetNext())
{
if (obj->GetMarker().IsEqual(objMarker))
{
return obj;
}
else
{
// check children
BaseObject* childObj = obj->GetDown();
if (childObj)
{
BaseObject* found = getObjectByMarker(doc, objMarker, childObj);
if (found)
{
return found;
}
}
}
}
return nullptr;
}
BaseTag* getTagByMarker(const BaseDocument& doc, const GeMarker& objMarker, const GeMarker& tagMarker)
{
BaseObject* obj = getObjectByMarker(doc, objMarker);
if (obj)
{
for (BaseTag* tag = obj->GetFirstTag(); tag; tag = tag->GetNext())
{
if (tag->GetMarker().IsEqual(tagMarker))
{
return tag;
}
}
}
return nullptr;
}
-
I found I cannot read the cloned vertex color tag's data from the cloned document, because the owner of the cloned object is not an instance of
Opoint
.
According to the document, to read data from vertex color tag, I need to get the point count of thepolyObject
who owns the vertex color tag.To do that, the
BaseObject
returned fromBaseTag::GetObject()
will need to be converted toPointObject
, thenPointObject::GetPointCount()
will be used to to get the point count.
However, I found if the tag is from a cloned document, theBaseObject
returned fromBaseTag::GetObject()
is not an instance ofOpoint
, so it cannot be converted toPointObject
.I can confirm that the
BaseObject
got from the original tag in the original document can be converted toPointObject
.I try to use the object from the cloned document, because I think the point count might change in a different frame. (The cloned document is at a different time)
BTW, the cloned document is created by
doc->GetClone(COPYFLAGS::PRIVATE_IDENTMARKER, nullptr)
.
Sorry for the long list, please let me know if I need to split above questions to different topics.
Now, all these questions above make me wonder if the usage is designed appropriately.
Maybe from C4D design's point of view, it is not a proper design to let user specify the time (different with the current frame, and even can be a earlier frame) when the tag's data should be used to render all frames?
Thank you!