Tparticle data not available in Python?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/08/2011 at 03:37, xxxxxxxx wrote:

    Hi all,

    I'm trying to access the particle data of a standard emitter. I can get the BaseContainer etc. of the Tparticle tag just fine, the GetDataCount() gives me the correct number of entries. However, every entry in the array that is being returned from GetData() is of type None and empty. What's going on?

    Cheers
    Michael



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 26/12/2011 at 14:10, xxxxxxxx wrote:

    I'd be happy to know how as well how to get the particle positions of a Standard Emitter.
    The SDK looks very sparse and I can't get my head around it.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 27/12/2011 at 15:02, xxxxxxxx wrote:

    AFAIK. Particle positions are stored in the object. Not the invisible particle tag.
    So based on that. It seems like the first thing we have to do is get at the particle object first. And that's where I'm stuck with it.
    I don't know how to convert the "BaseObject" type emitter  to a "ParticleObject" type with python.

    This is a simple example using C++:

    //Basic particle object example  
      
      BaseObject *obj = doc->GetActiveObject();  
      if(!obj) return FALSE;  
      
      if(obj->GetType()==Oparticle)                                //If the active object is an emitter  
       {  
        ParticleObject *po = (ParticleObject* )obj;                  //Assign it to a particle type variable "po"  
        ParticleTag    *pt = (ParticleTag* )obj->GetTag(Tparticle);  //The invisible tag that stores the particles  
        LONG pcnt = po->GetParticleCount();                         //Get the number of particles       
        LONG life = po->GetLifetime();  
        //GePrint(LongToString(pcnt));  
        //GePrint(LongToString(life));  
      
        Particle *pc = (Particle* )pt->GetLowlevelDataAddressW();  
        Vector pos = pc->off;              //Get the first particle's position  
        GePrint(LongToString(pos.z));  
      
        const Particle *p1  = NULL;  
        p1 = po->GetParticleR(pt,1);      //Get the second particle in the array of particles  
        Vector p1pos = p1->off;           //Get the second particle's position  
        GePrint(LongToString(p1pos.z));  
      
        const Particle *p10  = NULL;  
        p10 = po->GetParticleR(pt,10);   //Get the 11th particle in the array of particles  
        Vector p10pos = p10->off;        //Get the 11th particle's position  
        GePrint(LongToString(p10pos.z));  
      
       }
    

    Everything works in this C++ example because it's getting the particle data from the ParticleObject.
    I have no clue how to do the same thing with python. Because I don't know how to get at the ParticleObject with it.
    All we seem to have access to is the BaseObject emitter object in python.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 27/12/2011 at 17:02, xxxxxxxx wrote:

    Thanks Scott. I think I need a more Pythonesqe nudge to understand I'm afraid
    My efforts all end in a "cannot create 'c4d.module.particles.Particle' instances" error.

    Cheers
    Lennart



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 27/12/2011 at 19:49, xxxxxxxx wrote:

    ^ Yeah..That one got me too.
    I can get you a bit closer:

    import c4d  
    import c4d.modules.particles as ptcl  
      
    def main() :  
      
      bp = ptcl.BaseParticle  
      po = ptcl.Particle  
      #pmat = ptcl.CalcParticleMatrix(po) #<--Can't figure this one out yet  
      
      print po  
      print po.off  
      print po.v3  
      
    if __name__=='__main__':  
      main()
    

    But I still can't get at the specific particle position data yet.
    I wonder if Maxon support is off this week for the holidays?
    Usually Yannick would pop in by now.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/12/2011 at 02:46, xxxxxxxx wrote:

    First, I'm afraid ParticleObject class is not wrapped by the Python API.

    But I think we should be able to get the particles positions with the particle tag like done in the C++ example:

    import c4d
    from c4d.modules import particles 
      
    def main() :
      
        if op.GetType() == c4d.Oparticle:
            pt = op.GetTag(c4d.Tparticle)
            buffer = pt.GetLowlevelDataAddressW()
            for part in buffer:
                print part
            
      
    if __name__=='__main__':
        main()
    

    Remember that GetLowlevelDataAddressW() returns a ByteSeq buffer and the items are strings.

    I ran the code but got '-'. I need some help on using the standard particles emitter 🙂.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/12/2011 at 13:54, xxxxxxxx wrote:

    Thanks for looking into it Yannick.
    Would mean a lot to get it sorted.

    Cheers
    Lennart



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/12/2011 at 15:44, xxxxxxxx wrote:

    Meanwhile for my purposes I can use brute force cache
    as I only need the positions. Just need to have my
    generator later in the OM to get the cache.

      
    space = 0   
    pcm      = myGeneratorObject.GetMg()   
    scpoints = []   
      
    if lobj.CheckType(c4d.Oparticle) and lobj.GetDown() and lobj.GetCache() : # Standard Particle Emitter with child   
         lobjm   = lobj.GetMg()   
         cobj    = lobj.GetCache()   
         gchilds = cobj.GetChildren()   
         for i in gchilds:   
              sppoint = ~pcm*lobjm*i.GetAbsPos() if space == 0 else i.GetAbsPos()   
              scpoints.append(sppoint)   
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 28/12/2011 at 18:52, xxxxxxxx wrote:

    Good find Lennart.
    I knew the particles were stored in the emitter object. But I never would have guessed that we would need to use something like: Emitter.GetCache().GetChildren() to access them.

    If the "Show Objects" option on the standard emitter is on. We can get their positions using those functions:

    #Note: "Show objects" must be enabled on the emitter  
      
    import c4d  
      
    def main() :  
      
      ptclpositions = []                      #List to hold the particle positions  
      emitter = doc.SearchObject("Emitter")   #The particle emitter   
      
      if emitter.CheckType(c4d.Oparticle) and emitter.GetDown() and emitter.GetCache() : #Standard Particle Emitter with child  
         emittercache = emitter.GetCache()  
         particles = emittercache.GetChildren()  
      
         for particle in particles:  
              pos = particle.GetAbsPos()      #Get the position of each particle  
              ptclpositions.append(pos)       #Add it to the list "particlepos"  
      
      print ptclpositions                     #The list with the particle positions in it  
      
    if __name__=='__main__':  
      main()
    

    -ScottA


Log in to reply