Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 02/03/2012 at 09:51, xxxxxxxx wrote:
Hi all. This is my first post here. I've tried on and off again to begin coding, never being able to get over that first major hump. I've finally been able to put together some code well enough that I can start to ask advice without feeling like I'm goin' "deeerp, how you do code?!?!"
Now, This code is from a R12 python node in XPresso. It is functional, but probably pretty damn ugly. It would be great if someone could look it over and say "This huge chunk could have been this one line dummy!" Or "Why would you even DO that?"
Its function is to take an input 'link' and return the total poly count of the objects entire hierarchy, be they prim, generated, or whatever.
import c4d #Welcome to the world of Python def polyCheck(op) : # successfully gets polys from poly prims, and polygon objects. Ignores splines and nulls. probably pretty clunky if c4d.C4DAtom.GetType(op) == 5100: print op.GetName() + " Poly" return op.GetPolygonCount() elif op.GetCache() != None and (op.GetRealSpline()) == None: print op.GetName() + " non-poly poly" return op.GetCache().GetPolygonCount() elif op.GetCache() != None and (op.GetRealSpline()) != None: print op.GetName() + " spline" return 0 else: print "none" return 0 def addition(tempCount,op,placement) : print "#" + str(op.GetName()) + " polycount of " + str(tempCount) + " runs at " + str(placement) def count(op,base,tempCount) : #Runs through hierarchy, real ugly I bet. print "-----New 'def count'-----" while (op.GetDown() != None) and (op != base) : tempCount = tempCount + polyCheck(op) addition(tempCount,op,1) op = op.GetDown() if op.GetDown() == None and (op != base) and op.GetNext() == None: tempCount = tempCount + polyCheck(op) addition(tempCount,op,2) if op.GetNext() != None and (op != base) : tempCount = tempCount + polyCheck(op) addition(tempCount,op,3) op = op.GetNext() if op.GetNext() == None and (op != base) and op.GetDown() == None: tempCount = tempCount + polyCheck(op) addition(tempCount,op,4) tempCount = count(op,base,tempCount) else: if op.GetNext() == None and op.GetDown() == None and op.GetPred() == None and op.GetUp() == base: tempCount = tempCount + polyCheck(op) while op.GetNext() == None and (op != base) : op = op.GetUp() if op.GetNext() != None and (op != base) : op = op.GetNext() if op.GetNext() == None and op.GetDown() == None: tempCount = tempCount + polyCheck(op) tempCount = count(op,base,tempCount) else: tempCount = count(op,base,tempCount) print str(tempCount) + " COUNT5" return tempCount def main() : global PolyCount #for Output tempCount = 0 PolyCount = 0 #from input if ConnectObject.GetDown() == None: PolyCount = PolyCount + polyCheck(ConnectObject) else: PolyCount = count(ConnectObject.GetDown(),ConnectObject,tempCount) PolyCount = PolyCount + polyCheck(ConnectObject) print PolyCount print "--Done--"
import c4d #Welcome to the world of Python
def polyCheck(op) : # successfully gets polys from poly prims, and polygon objects. Ignores splines and nulls. probably pretty clunky
if c4d.C4DAtom.GetType(op) == 5100: print op.GetName() + " Poly" return op.GetPolygonCount() elif op.GetCache() != None and (op.GetRealSpline()) == None: print op.GetName() + " non-poly poly" return op.GetCache().GetPolygonCount() elif op.GetCache() != None and (op.GetRealSpline()) != None: print op.GetName() + " spline" return 0 else: print "none" return 0
def addition(tempCount,op,placement) : print "#" + str(op.GetName()) + " polycount of " + str(tempCount) + " runs at " + str(placement)
def count(op,base,tempCount) : #Runs through hierarchy, real ugly I bet. print "-----New 'def count'-----"
while (op.GetDown() != None) and (op != base) : tempCount = tempCount + polyCheck(op) addition(tempCount,op,1) op = op.GetDown() if op.GetDown() == None and (op != base) and op.GetNext() == None: tempCount = tempCount + polyCheck(op) addition(tempCount,op,2) if op.GetNext() != None and (op != base) : tempCount = tempCount + polyCheck(op) addition(tempCount,op,3) op = op.GetNext() if op.GetNext() == None and (op != base) and op.GetDown() == None: tempCount = tempCount + polyCheck(op) addition(tempCount,op,4) tempCount = count(op,base,tempCount)
else: if op.GetNext() == None and op.GetDown() == None and op.GetPred() == None and op.GetUp() == base: tempCount = tempCount + polyCheck(op)
while op.GetNext() == None and (op != base) : op = op.GetUp()
if op.GetNext() != None and (op != base) : op = op.GetNext() if op.GetNext() == None and op.GetDown() == None: tempCount = tempCount + polyCheck(op) tempCount = count(op,base,tempCount) else: tempCount = count(op,base,tempCount)
print str(tempCount) + " COUNT5" return tempCount
def main() : global PolyCount #for Output tempCount = 0 PolyCount = 0 #from input
if ConnectObject.GetDown() == None: PolyCount = PolyCount + polyCheck(ConnectObject) else: PolyCount = count(ConnectObject.GetDown(),ConnectObject,tempCount) PolyCount = PolyCount + polyCheck(ConnectObject) print PolyCount print "--Done--"
Thanks in advance for any advice on cleaning this up. I'm excited to finally be able to post something!
Chris Schmidt
On 02/03/2012 at 10:47, xxxxxxxx wrote:
Hello Chris,
here are some things you should take care of:
import c4d def getPolygonCountRec(op) : """ Returns the number of polygons for an object recursively. Always succeeds, for generator and polygon-objects. Returns an integer. """ # Return the number of polyogns when the object is a PolygonObject. if op.CheckType(c4d.Opolygon) : return op.GetPolygonCount() # Return zero when the object is a spline. elif op.CheckType(c4d.Ospline) : return 0 # Or go on recursively if both do not apply else: cache = op.GetCache() if not cache: return 0 count = getPolygonCountRec(cache) for child in cache.GetChildren() : count += getPolygonCountRec(child) return count def main() : global PolyCount if not InputObject: PolyCount = 0 else: PolyCount = getPolygonCountRec(InputObject)
The code expects the variable InputObject to be available in the global scope (i.e. an input-port in the XPresso node). The value of the polygon-count will be assigned to the variable PolyCount, so you need to create an output-port named like this.
Greetings, Niklas
On 08/03/2012 at 18:59, xxxxxxxx wrote:
Thanks so much Niklas! Incredibly generous and helpful.
We've tried to rework the code so that we can iterate through a hierarchy. It seems to work perfectly with the exception of HyperNURBS ( and symmetry object) Where the count is always off. Is there some special way to treat these types of generator objects?
import c4d def childLoop(op,count) : #Goes down children recursively for child in op.GetChildren() : count += getPolygonCountRec(child) return count def getPolygonCountRec(op) : """ Returns the number of polygons for an object recursively. Always succeeds, for generator and polygon-objects. Returns an integer. """ # Return the number of polyogns when the object is a PolygonObject. Goes down children recursively count = 0 if op.CheckType(c4d.Opolygon) : count = op.GetPolygonCount() count = childLoop(op,count) return count # Return zero when the object is a spline. Goes down children recursively elif op.CheckType(c4d.Ospline) : count = childLoop(op,count) return count # Or go on recursively if both do not apply. Goes down children recursively else: cache = op.GetCache() count = childLoop(op,count) if cache: if not cache.GetChildren() : count += getPolygonCountRec(cache) if cache: count = childLoop(cache,count) return count def main() : global PolyCount if not ConnectObject: PolyCount = 0 else: PolyCount = getPolygonCountRec(ConnectObject) #(InputObject)
import c4d
def childLoop(op,count) : #Goes down children recursively for child in op.GetChildren() : count += getPolygonCountRec(child) return count
def getPolygonCountRec(op) : """ Returns the number of polygons for an object recursively. Always succeeds, for generator and polygon-objects. Returns an integer. """
# Return the number of polyogns when the object is a PolygonObject. Goes down children recursively count = 0 if op.CheckType(c4d.Opolygon) : count = op.GetPolygonCount() count = childLoop(op,count) return count
# Return zero when the object is a spline. Goes down children recursively elif op.CheckType(c4d.Ospline) : count = childLoop(op,count) return count
# Or go on recursively if both do not apply. Goes down children recursively else: cache = op.GetCache() count = childLoop(op,count) if cache: if not cache.GetChildren() : count += getPolygonCountRec(cache) if cache: count = childLoop(cache,count) return count
def main() : global PolyCount if not ConnectObject: PolyCount = 0 else: PolyCount = getPolygonCountRec(ConnectObject) #(InputObject)
Thanks again for any help!
On 09/03/2012 at 10:12, xxxxxxxx wrote:
What do you mean by "The count is always off" ? The code works for me.
Cheers, -Niklas
PS: Cleaned it up a bit.
import c4d def recursion(op) : count = 0 for child in op.GetChildren() : count += recursion(child) if op.CheckType(c4d.Opolygon) : return op.GetPolygonCount() + count elif op.CheckType(c4d.Ospline) : return count else: cache = op.GetCache() if not cache: return count return recursion(cache) + count def main() : global PolyCount if ConnectObject: PolyCount = recursion(ConnectObject) else: PolyCount = 0 return True
On 09/03/2012 at 23:05, xxxxxxxx wrote:
Thanks once again Niklas, I have much to learn. Your new code works perfectly!
The problem with the count I was referencing is if you take a single polygon and put in as child of a HyperNURB the code returns 5. Same problem with symmetry object. I assume it's because it's counting the HyperNURB AND the single polygon, however if you use something like a cloner it works just fine. Just wondering what the reason for that is and if there was any way around it.
Chris
On 10/03/2012 at 02:43, xxxxxxxx wrote:
Hi Chris,
I see, no it doesn't work correctly. I get 102 polygons for a HyperNurbs with a cube of 6 faces. It should be 96 polygons, but + 6 of the cube = 102. To work around this we'd need to know if the object we're currently at is a generator object based on children or not.. We could collect all the objects doing this, but then we don't include plugins that do so, etc.
I'm not sure, but when registering an object plugin to c4d you must tell it that your plugin works with the children and maybe there is a possibility to get that flag from Python..? (Looking over to maxon..)
~~I don't think the whole thing will be of use for you. Unfortuneately, we can not access the cache when rendering.. Or, at least not in the first frame or .. ah i don't understand it. Refer to this threads:
https://plugincafe.maxon.net/topic/5830/5888_the-cache-while-rendering https://plugincafe.maxon.net/topic/6272/6658_no-attributes starting at post #9~~
Edit: It works while rendering when setting the Priority to Generators. Thanks to Lennart!
I added a few debugging lines to the code to see what happens when rendering:
import c4d def recursion(op, i = 0) : print " " * i + op.GetName() + " :: " + op.GetTypeName() count = 0 for child in op.GetChildren() : count += recursion(child, i+4) if op.CheckType(c4d.Opolygon) : return op.GetPolygonCount() + count elif op.CheckType(c4d.Ospline) : return count else: cache = op.GetCache() if not cache: return count print " " * (i+5) + "--- cache ---" return recursion(cache, i+5) + count def main() : global PolyCount if ConnectObject: PolyCount = recursion(ConnectObject) else: PolyCount = 0 return True
This is the output in the editor:
HyperNURBS :: HyperNURBS Würfel :: Würfel --- cache --- Würfel :: Polygon-Objekt --- cache --- Würfel :: Polygon-Objekt
This is the output when rendering:
HyperNURBS :: HyperNURBS Würfel :: Würfel
You notice there is no cache available? The polygoncount is zero (for only primitves, we can still access polygonobjects from he OM).
Cheers, Niklas
On 12/03/2012 at 15:22, xxxxxxxx wrote:
The Priority to Generators bit is over my head, as my HyperNURBS still returns the wrong number. But I learned some useful things from your debugging! And your previous code seems to suite my puposes perfectly! Now I'm off to write more code : )