ok, my apologies. i guess my question is at what point to i check for dirty, and at what point do i insert the nulls?
Best posts made by Eduardo Oliveira
Latest posts made by Eduardo Oliveira
Thanks for the reply - sorry to resurrect this post, but I am still struggling to put your advice to use. since I am mostly writing this plugin to learn, I'll go ahead and just paste the code in here ( please be gentle)
class CloneStalker (plugins.ObjectData):
def init (self):
self.SetOptimizeCache(True)
def Init(self, node):
# Parameter initialization
self.InitAttr(node, float, [c4d.CL_STALKER_MAX_NULLS])
node[c4d.CL_STALKER_MAX_NULLS] = 100.0
pd = c4d.PriorityData()
if pd is None:
raise MemoryError("Failed to create a priority data.")
pd.SetPriorityValue(c4d.PRIORITYVALUE_MODE, 4)
pd.SetPriorityValue(c4d.PRIORITYVALUE_PRIORITY, 100)
node[c4d.EXPRESSION_PRIORITY] = pd
return True
def CheckDirty(self, op, doc):
frame = doc.GetTime().GetFrame(doc.GetFps())
if frame != lastFrame:
lastFrame = frame
op.SetDirty(c4d.DIRTYFLAGS_DATA)
def AddToExecution(self, op, list) :
list.Add(op, c4d.EXECUTIONPRIORITY_GENERATOR, 400)
return True
def GetVirtualObjects(self, op, hh):
cloner = op[c4d.CL_STALKER_TARGET]
doc = c4d.documents.GetActiveDocument()
def GetStalkers(bname,tgt):
allChild = tgt.GetChildren()
stalkerChilds = []
if allChild != None:
for i in allChild:
childname = i[c4d.ID_BASELIST_NAME]
bnamelenght = len(bname)
subname = childname[0:bnamelenght]
if subname == bname:
stalkerChilds.append(i)
return stalkerChilds
if cloner != None:
modata=mo.GeGetMoData(cloner)
if modata != None:
cache = cloner.GetDeformCache()
if cache is None:
cache = cloner.GetCache()
clones = cache.GetChildren()
name = str(cloner[c4d.ID_BASELIST_NAME]) + ".Cloner Stalker"
child_basename = op[c4d.ID_BASELIST_NAME].replace(".Cloner Stalker", ".Stalker.")
if cloner.GetNext() != op:
op.InsertAfter(cloner)
null= c4d.BaseObject(c4d.Onull)
null[c4d.NULLOBJECT_DISPLAY]=0
null[c4d.ID_BASELIST_NAME] = name
parent=op
md = mo.GeGetMoData(cloner)
marr = md.GetArray(c4d.MODATA_MATRIX)
count = md.GetCount()
Selection = []
maxNulls = op[c4d.CL_STALKER_MAX_NULLS]
lastChild = None
child = GetStalkers(child_basename,op)
if mo.GeGetMoDataSelection(cloner) == None:
for i in range(count):
Selection.append(i)
selected=Selection
if mo.GeGetMoDataSelection(cloner)!= None:
Selection = mo.GeGetMoDataSelection(cloner).GetAll(count)
selected=[i for i,x in enumerate(Selection) if x==1]
if op[c4d.ID_BASELIST_NAME]!=name:
child_basename = op[c4d.ID_BASELIST_NAME].replace(".Cloner Stalker", ".Stalker.")
if len(child)>0:
for i in child:
old_name =i[c4d.ID_BASELIST_NAME]
index_name = old_name[len(child_basename):len(old_name)]
n_name = cloner[c4d.ID_BASELIST_NAME] + ".Stalker." + index_name
i[c4d.ID_BASELIST_NAME] = n_name
print (n_name)
op[c4d.ID_BASELIST_NAME] = name
child_basename = op[c4d.ID_BASELIST_NAME].replace(".Cloner Stalker", ".Stalker.")
child = GetStalkers(child_basename,op)
parent=op
op.SetMg(cloner.GetMg())
if len(child)<len(selected) and len(child) < maxNulls:
currChilds=[]
for i in child:
child_name = i[c4d.ID_BASELIST_NAME]
nameLenght = len(child_name)
index = int(child_name[len(child_basename):nameLenght])
currChilds.append(index)
new = [item for item in selected if item not in currChilds]
for i in new:
obj= c4d.BaseObject(c4d.Onull)
obj[c4d.ID_BASELIST_NAME] = child_basename + str(i)
obj[c4d.NULLOBJECT_DISPLAY]=3
obj[c4d.NULLOBJECT_RADIUS]=50
extCompTag = c4d.BaseTag(465000402)
matrix = clones[i].GetMg()
obj.SetMg(matrix)
obj.InsertTag(extCompTag)
if len(child)>0:
lastChild = child[(len(child)-1)]
doc.InsertObject(obj,parent,lastChild)
child = GetStalkers(child_basename,op)
if len(child)==maxNulls:
break
if len(child)>len(selected) or len(child)>maxNulls:
for i in child:
child_name = i[c4d.ID_BASELIST_NAME]
nameLenght = len(child_name)
index = child_name[len(child_basename):nameLenght]
if not int(index) in selected:
i.Remove()
child = GetStalkers(child_basename,op)
while len(child)>maxNulls:
lastChild = child[(len(child)-1)]
lastChild.Remove()
child = GetStalkers(child_basename,op)
def Execute(self, op, doc, bt, priority, flags) :
def GetStalkers(bname,tgt):
allChild = tgt.GetChildren()
stalkerChilds = []
if allChild != None:
for i in allChild:
childname = i[c4d.ID_BASELIST_NAME]
bnamelenght = len(bname)
subname = childname[0:bnamelenght]
if subname == bname:
stalkerChilds.append(i)
return stalkerChilds
cloner = op[c4d.CL_STALKER_TARGET]
doc = c4d.documents.GetActiveDocument()
name = str(cloner[c4d.ID_BASELIST_NAME]) + ".Cloner Stalker"
child_basename = op[c4d.ID_BASELIST_NAME].replace(".Cloner Stalker", ".Stalker.")
parent=op
child = GetStalkers(child_basename,op)
Selection = []
if cloner != None:
modata=mo.GeGetMoData(cloner)
if modata != None:
cache = cloner.GetDeformCache()
if cache is None:
cache = cloner.GetCache()
clones = cache.GetChildren()
md = mo.GeGetMoData(cloner)
marr = md.GetArray(c4d.MODATA_MATRIX)
count = md.GetCount()
if mo.GeGetMoDataSelection(cloner) == None:
for i in range(count):
Selection.append(i)
selected=Selection
if mo.GeGetMoDataSelection(cloner)!= None:
Selection = mo.GeGetMoDataSelection(cloner).GetAll(count)
selected=[i for i,x in enumerate(Selection) if x==1]
for x in selected:
matrix = clones[x].GetMg()
ch_name = child_basename + str(x)
obj=c4d.documents.BaseDocument.SearchObject(doc,ch_name)
obj.SetMg(matrix)
print (clones[x].IsDirty(1))
return c4d.EXECUTIONRESULT_OK
Please feel free to advise what i am doing wrong here, and what shuold i be doing instead.
many thanks for your patience.
cheers
Eddie
Hi All,
I'm on my first plugin, and by no means a true Python developer.
my plugin is relatively simple : it gets a cloner from a LINK box in the GUI, and creates a null for each clone, with a compositing tag attached, and gets the matrix of each clone from the GetCache() and applies it to each null, making them follow the clones.
It all works fine on the viewport, but if i export an AEC file, the nulls are all static, and not following changes caused by effectors, like position or rotation etc. it DOES work on the viewport as you scrub the timeline in C4D though.
i'm creating the Nulls during the GetVirtualObjects() function, and changing their Matrix on the Execute() function.
Any ideas?
Cheers,
Eddie
Apologies if this has been answered before, but I could not find it by searching.
my plugin makes a null follow the matrix of another object. problem is that because of priorities unless the plugin object is after the "target" it is always one frame behind ( or it snaps on position when you refresh the viewport)
my plugin is based on ObjectData, and is a Generator, not a tag, so how do I go about changing the priority so that the code only runs after the target's matrix has been calculated?
i'd much appreciate a "dummies" explanation, as I am still only dipping my toes into programming and plugin dev
Many thanks,
Eddie