On 28/04/2016 at 09:18, xxxxxxxx wrote:
Hi all,
I think I am most likely just misusing the Python Generator due to my own misunderstanding, but I find it odd that it actually does work... just inconsistently.
I have a simple linkage setup that consists of an IK-chain under one "pivot" null, and the IK-goal under a second "pivot" null. I need multiple copies of this "linkage" to be aligned to a spline, yet retain the individual IK-chain calculations. Since I can't get that with a cloner, I've gone the route of multiple copies with Align-To-Spline tags, one on each pivot point under the "linkage" parent null. With the second pivot offset a fixed small %, all sets of linkages can then be driven around the spline with iterative offset/modulo calculations.
However, I want to be able to dynamically input the number of linkages (i.e. sets of two pivots) that are on a given spline. My first attempt has been to use a Python Generator object with user data (links for the spline, linkage parent null, number of linkages, offset %, and phasing %). The PyGen object would look at the desired number of links, and create copies equal to that number, as children of itself. This involves deleting the current children, and creating new copies as needed.
Using primitive objects as my pivot points under a parent null, the following works just as I had hoped--I can swap out geometry, change the link size, number of links, and offset values; with no problems whatsoever:
import c4d
from c4d.utils import SplineHelp
def main() :
spline = op[c4d.ID_USERDATA,1] #USER INPUT LINK FIELD FOR THE SPLINE
master = op[c4d.ID_USERDATA,2] #USER INPUT LINK FIELD FOR THE LINKAGE GEOMETRY
#(Single parent null, with some # of pivot nulls as children)
numLink = op[c4d.ID_USERDATA,3] #USER INPUT INTEGER FOR TOTAL NUMBER OF LINKAGES
currentLinks = op.GetChildren() #COUNT UP THE CURRENT NUMBER OF LINKS
#THAT ARE UNDER THE PYGEN OBEJCT
offset = op[c4d.ID_USERDATA,4] #User input FLOAT (%) for driving links around spline
phase = op[c4d.ID_USERDATA,5] #Addn'l input FLOAT (%) to shift the links +/- if necc
linkLen = op[c4d.ID_USERDATA,7] #User inpu FLOAT (inches) to space the pivot points
sh = SplineHelp()
sh.InitSpline(spline)
slen = sh.GetSplineLength() #Measure the input spline length
sh.FreeSpline()
if len(currentLinks) != numLink: #Check if the user changed the number of links
for link in currentLinks:
link.Remove() #<<============= Here's where I think I'm running into trouble
if master != None: #If a master linkage GEO is provided...
for i in range(0,numLink) : #create copies of the master link, insert under pyGen obj
copy = master.GetClone()
copyName = copy.GetName()
name = copyName + "_%i"%(i+1)
copy.SetName(name)
copy.InsertUnderLast(op)
i = 0
cnt = float(len(currentLinks))
ind = linkLen/slen #Calculate small offset % based on space between pivots
for link in currentLinks:
pivots = link.GetChildren()
j=0
for pivot in pivots:
atsTag = pivot.GetTag(c4d.Taligntospline) #Check for an ATS tag
if atsTag:
off = (((i/cnt+ind*j)%1+offset)%1+phase)%1 #Calculate offset for each ATS tag
atsTag[c4d.ALIGNTOSPLINETAG_LINK] = spline
atsTag[c4d.ALIGNTOSPLINETAG_POSITION] = off
j+=1
i+=1
When I test it on my two-pivot linkage that involves an IK chain, it copies/distributes the objects just fine, and they all animate around the spline just fine.... But as soon as I try to change the numLink value [which would invoke the .remove() command], C4D throws a bug-report dialog and the whole works freezes.
So... am I to understand this is exactly what is described in the SDK as what NOT to do? I thought if the code in the pyGen object qualified as an expression in a node , then this should've crashed when I used it with primitives. Do I need to do some kind of c4d.StopAllThreads() first? (I'm assuming that would NOT work since it would stop my PyGen object too, correct?)I am not a programmer, so it's a shot in the dark for me at this point.
If anyone has thoughts as to why this works in one case, and not the other, and advice as to what would be the RIGHT way, I would greatly appreciate the input!
--Marcus