Basic array question



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

    On 11/05/2007 at 11:17, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   9.1 
    Platform:      Mac OSX  ; 
    Language(s) :   C.O.F.F.E.E  ;   XPRESSO  ;

    ---------
    Hello, I'm trying to learn how to use C.O.F.F.E.E. and Xpresso so I can use external data to drive object parameters in a C4D scene. So far, I've got my data in okay, and split it up into an array (with frame numbers as the index) so I can then call up a different bit of data depending on the current frame.

    Problem is, I have my code between the main() {} tags and it was running the array filling code on every frame. To stop this, I put in an if statement to say 'only do it on the first frame', but then if I try to reference my array on any frame except the first one the array is blank. How can I get the data to persist throughout my movie?

    I have quite a lot of experience with ActionScript, which isn't a million miles away from C.O.F.F.E.E. but obviously many things work differently! Any help would be much appreciated.

    Cheers

    Jamie



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

    On 11/05/2007 at 12:43, xxxxxxxx wrote:

    Expressions (COFFEE/Xpresso) are called on every frame of an animation.

    If the data already exists (external data), I wouldn't preload it like this if possible. Access it by frame index instead into the external data. But I'm unclear about your entire procedure with code. If this external data is in a file, sounds like you may need two separate things - one to load the data in an array and the other to work on the data.

    ETA: The problem here is 'persistence'. The array is probably being initialized for each Expression pass (each frame). You'll need that array someplace where it will persist.



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

    On 13/05/2007 at 06:10, xxxxxxxx wrote:

    I'm not sure I entirely follow you ( Access it by frame index instead into the external data ). Basically, I'm pasting in a string of values, separated by ";" and ":" then running a little script to split up the data based on the seperators and file it all away into an array. I figured pasting the information into a 'Constant' node would be easier than loading an external text file, as I haven't had chance to figure out how to do that!

    The persistence bit does make sense to me, however I can't work out where to put it that I would be able to do that. If initialize the array within the 'if' statement I mentioned before (so it will only all happen on the first frame) it seems I can't access the data outside the 'if'?

    If (ha!) it helps, this is where I'm currently at, but it won't compile properly as it says '...Line: 56 Col :13 Error: Variable or function expected', which I'm assuming is because it doesn't know the array exists? My string would be something like this:
    0:2826:39:63;
    720:1289:29:66;
    1440:1457:34:70;

      
    main()  
    {  
    if (Frames == 0) {  
    var pttrn = new(array, 8); // input split into array  
    var pttrn1 = new(array, 10000, 4); // pattern split into 2D array  
         /////////////take DataIn string and split up into each individual note/////////////////  
         var str;  
         var value;  
         var input = DataIn;  
         var ntOn;  
         var lnBrk = ";"[0];  
         var brkLoc = strchr(input, lnBrk)+1;  
         var j;  
         for (j=0; j <= 7; j++) {  
              var brkLoc = strchr(input, lnBrk)+1;  
              if (brkLoc == 0) {  
                   str = input;  
              }     else {  
                   var inputTmp = strmid(input, brkLoc, 2000);  
                   str = strmid(input, 0, brkLoc-1);  
                   input = inputTmp;  
              }  
              //////////take note on/length/pitch/vol data and split into array////////////  
              var i;  
              var strTmp;  
              var ntOn;  
              var char = ":"[0];  
           
              for (i=0; i <= 3; i++) {  
                   var charLoc = strchr(str, char)+1;  
                   if (charLoc == 0)     {  
                        value = evaluate(str);  
                   }     else     {  
                        var strTmp = strmid(str, charLoc, 20);  
                        value = evaluate(strmid(str, 0, charLoc-1));  
                        str = strTmp;  
                   }  
                   if (i == 0) {  
                        ntOn = int(value);  
                        pttrn1[ntOn] _= ntOn;  
                   } else {  
                        pttrn1[ntOn] _= int(value);  
                   }  
                   //println(pttrn1[ntOn] _);  
              }  
         }  
    }  
    ////////////////////////  
    if (Frames >= 0) {  
         var x = Frames;  
         if (pttrn1[x][1] != nil) {  
              NoteLength = pttrn1[x][1];  
              Pitch = pttrn1[x][2];  
              Vol = pttrn1[x][3];  
              println(pttrn1[x][1]);  
         }  
    }  
    }  
    


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

    On 13/05/2007 at 10:40, xxxxxxxx wrote:

    That code definitely will not work. First, pttrn1 is out of scope in the "if (Frames >= 0) {}" section as it is only defined within the "if (Frames == 0) {}" section. I think you have noticed this. You could fix that like this:

    main()
    {
    var pttrn1 = NULL;
    if (Frames == 0)
    {
    pttrn1 = new(array, 10000 4);
    ...
    }
    if (Frames >= 0)
    {
    ....
    }

    Then it will be within scope for the second conditional section. Unfortunately, pttrn1 will be NULL on subsequent frames. One solution would be to new() the array for every frame - but that means reloading the data for every frame. Remember that this expression is called anew on every frame of the animation - starting at main(). There is nothing retained between invocations of the expression - even between frames.

    You can't win trying to work an expression this way on an animation. Basically, you need a preprocessing phase to import the data into a storage outside the scope of this expression so that it persists independent of it and access it with the expression somehow. Maybe there is another Xpresso node that can serve this purpose? I'm thinking some COFFEE plugin object might be better here as they are guaranteed to persist.

    Also, if I'm reading the COFFEE docs correctly, COFFEE expressions are locked out of file access - this does not affect COFFEE plugins (.cof) - see COFFEE Docs under "Basic functions and classes". Don't know if this extends to COFFEE in Xpresso nodes.



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

    On 14/05/2007 at 11:11, xxxxxxxx wrote:

    Okay, thanks. I'm looking into using the Xpresso 'Memory' Node to store the split up strings, then spliting them up further when they are called. I'll post about how it goes if I work it out!

    I saw a post on another site whilst reseaching about people using point values of an object to store data. Might have a go at that too if I can't get there with the Memory node.

    Thanks again for your help!



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

    On 14/05/2007 at 12:08, xxxxxxxx wrote:

    Quick question (doesn't seem to be mentioned in the SDK) - can you use a variable to loop through input ports on a C.O.F.F.E.E. node? For example, if you had input ports labelled 'Input1', 'Input2', 'Input3' and so on, could you refer to 'Input n' via come sort of concatenation?


Log in to reply