get deformed points [SOLVED]

On 13/04/2017 at 08:30, xxxxxxxx wrote:


I'm trying to set up a python tag which detects the lowest point in an object (point which has lowest global Y position).

This works fine if I manipulate the object PSR directly, but if I try and do it with an effector, with deformer set to Object, for example, time effector with rotation, it doesn't work.

I tried setting the tag to priority: Generators but that didn't help.
I could potentially use the xpresso point node with "deformed points" ticked, but then I have to loop externally and it becomes stupid/messy.

On 13/04/2017 at 10:06, xxxxxxxx wrote:

I guess everything is explained here
Where you must use GetDeformCache() on a tag with the priority set to Generators.

On 14/04/2017 at 03:00, xxxxxxxx wrote:

Hi Nnenov, thanks for writing us.

With reference to your question I warmly suggest, as already done by gr4ph0s, to have a look at BaseObject class in the Python API documentation and more specifically to the BaseObject.GetCache() and BaseObject.GetDeformCache() methods which are those helping you to access the relevant data produced by generators and deformers.

To complete the answer find below a short example on how to use 'em in a Python Tag.

import c4d  
import sys
def FindFurtherNegativeY(obj) :  
  #initialize the largest positive vector  
  res = c4d.Vector(sys.float_info.max)  
  # retrieve the object global transformation matrix  
  objGloMtx = obj.GetMg()  
  # retrieve the object points  
  points = obj.GetAllPoints()  
  # loop over the points    
  for point in points:  
      # retrieve the point in global space  
      pointGlo = objGloMtx * point  
      if pointGlo.y < res.y:  
          # store the point if it's smaller then   
          # the latest small one  
          res = pointGlo  
  return res
def AccessCache(op) :  
  # verify existance of the deformed cache  
  temp = op.GetDeformCache()  
  if temp is not None:  
      # recurse over the deformed cache  
      # verify existance of the cache  
      temp = op.GetCache()  
      if temp is not None:  
          # recurve over the cache  
          # the relevant data has been found  
          # and it should not be a generator  
          if not op.GetBit(c4d.BIT_CONTROLOBJECT) :  
              # check the cache is an instance of Opoint  
              if op.IsInstanceOf(c4d.Opoint) :  
                  print FindFurtherNegativeY(op)  
  # traverse the object hierarchy  
  temp = op.GetDown()  
  while temp is not None:  
      temp = temp.GetNext()
def main() :  
  if op is None:  
  # look for the object to whom the tag belongs  
  obj = op.GetObject()  
  print obj  
  if obj is None:  

Best, Riccardo

On 14/04/2017 at 08:18, xxxxxxxx wrote:

Thank you both for your help.
I was not aware of this whole concept, this is all very enlightening.

Riccardo, I tried out your example code, I wanted to make use of this deformed value, but I tried to use "return" instead of "print" in the AccessCache def:

                if op.IsInstanceOf(c4d.Opoint) :
                    print FindFurtherNegativeY(op)
                    return FindFurtherNegativeY(op)

Then, in main() I put

print AccessCache(obj)

But it returns None rather than the min y vector. Yet, the print command inside of the AccessCache function prints the correct vector value..
My first guess is that this is due to the nature of recursive functions, but I'm not sure exactly why it is happening..

On 14/04/2017 at 08:49, xxxxxxxx wrote:

I am realising now, I should just put my code there in the function, rather than try and use return to access it in main(), but I am still curious about why this happens

On 20/04/2017 at 01:05, xxxxxxxx wrote:

Hi NNenov,

the reason is related to what the recursive function returns which is basically a None object. Adjusting the recursive function to return what is passed to the function responsible to print the further negative Y, while give you the chance to have returned the object you're interested to investigate in the main().

Cheers, Riccardo