What's the best way to learn Daz Scripting?

Ok, so from what I can gather, Daz Script 2 is an extension of QtScript, which is an extension of ECMAScript, which is a standardized form of JavaScript. So would I be better off learning JavaScript first, then moving to Daz Script? I ask because I'm a little bit old school (C=64 era) and I learn better when I have a book I can sit down and read. There are tons of books on JS, but I doubt I'd find any on DS. I'm familiar with programming (Basic, Cobol, Pascal) but the only modern language I've studied is Java.

Second, how similar is DS to JavaScript? Will learning JS first screw me up, or will it give me a solid foundation to learn DS more easily?

Comments

  • Jay VersluisJay Versluis Posts: 244

    The syntax of DAZ Script is idential to that of JavaScript, so I think a good first step is to learn JS first. DAZ Script has additions to JS that are applicable to DAZ Studio. For example, you can target a bone on a figure in your scene, much like you can traverse the DOM of a HTML document. 

    Most books on JS focus on web development, so they'll include a lot of HTML and server-side examples. Those aren't applicable to DAZ Script of course. Once you know the syntax of JS, you can plough through the DAZ Scripting docs and you're good to go.

    Good luck!

  • KitsumoKitsumo Posts: 1,210

    Thanks. The other day I was about to go to a bookstore to pick up a JavaScript book, when I saw that most of them only cover web development just like you said. I'll look for something programming oriented. Just my luck, the college I go to doesn't have any JS courses. They only have continuing education JS classes (for like $1200) that wouldn't apply to my major. I guess I'm taking the do-it-yourself route. No worries. Thanks for the reply.

  • nicsttnicstt Posts: 11,714
    edited July 2017

    Check out Udemy for courses, they often have offers available.

    Learning JS will be very helpful, even the DOM and anything related to Web Dev; most JS you see read about etc is client side not server side, although it is used server-side. (There is Java server-side too, but it isn't any more like JS than C sharp is.)

    Post edited by nicstt on
  • stitlownstitlown Posts: 276

    Hey guys, I'm just starting to dabble in scripting, with some success.  Like Kitsumo I once did old G1 languages (Fortran, Cobol, APL - and yes it was last century and relatively early in last century) but never really did modern languages.  Dabbled in Python for Vue when I used that.  The biggest problem I am finding is that I cannot locate references that make sense to me and which I can search.  eg I have scripts working that use .getWSPos() .setWSPos .getWSRot  .setWSRot but I have found nothing that gives me a reference on these or lists the other possible .get .set I might want to use (currently scale).  I have downloaded the old DS3 documentation per a Richard Hasletine pointer somewhere else but I just cannot find the references I presume must be there. Everything I've managed so far has basically been plundering other working scripts and intuiting how the bits I need "tick".

      Any pointers / tips / suggestions ???

  • stitlownstitlown Posts: 276
    edited July 2017

    Earlier post may be redundant as I've made good progress today (if stumbling around in the dark is good progress - haha).  Found most of the operators or methods (still not sure of my terminology) under DZNode and even got some traction on higher level stuff looking in DZScene  [all DS3 documentation].  Still earger for any hints or tips.  And a gold star to anyone who can help me understand how to move beween GUI rotations and the script Quaterion Rotations.

    Cheers.  Lx

    And I keep finding references to "the more efficient nodeListiterator" or lightListiterator etc. but I've not yet found any references on these. ???

    Post edited by stitlown on
  • Are you sure they aren't referring to things in the SDK (compiled C++ code) that aren't available in script, so a less efficient method has to be used?

  • stitlownstitlown Posts: 276
    edited July 2017

    Thanks Richard - no, I'm never sure of anything.  I just stumble around until something works "near enough".  I'll assume they are refering to SDK and stick with the "less efficient" ones I can find.

    For what it is worth for anyone out there who like me has struggled with quaterions, I finally actually studied it and I think got it enough to be able to work with it.  Attached is a "training and investigation" script I did that:

    - takes the first node in a list

    - gets the quaterion rotations

    - gets the euler angle rotations

    - converts the euler angles to degrees and splats it all to a message box so you can eyeball that these are the same as what is showing in the parameters tab.

    It is then very simple to change to the desired degrees, invert the degrees into radians and then convert them to a quaterion which you can apply to the node.  The second "free rotation" script does this for a Y axis alteration done to a bunch of nodes.  Hope this helps some other struggle-hard like me.  Cheers, Lx

     

    dsa
    dsa
    UnderstandingQuaterions.dsa
    539B
    dsa
    dsa
    FreeRotateY.dsa
    719B
    Post edited by stitlown on
  • Lonesome CowboyLonesome Cowboy Posts: 153
    edited August 2017

    Hi,

    i am experienced in coding php, basic, ... and i often use JavaScript too, but i do not like it very much.
    I have lots of books even about JavaScript and Jquery and so on, but this is the most difficult language i know.

    What i want to say is i know lots of basics in coding, but i am not perfect.
    It is difficult for me to understand how the code works and why the creator did this or thus.

    So i want to learn coding DAZ Script. YES, i know how to start the scriptint IDE and so on.
    I have also seen the Scripting Start Reference http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/start

    But what i need is the WAY how to go from start to a certain result:

    - What functions do i need to get my result?
    - What is the correct way to use them?
    - Which steps are neccessary in which order?
    - Which functions do belong together for reaching my results?
    - On which important things have i to think about?
    - What is the basic start with my project?

    Every coding book tells me these questions, but not the DAZ-Sites.
    In the examples there are some parts i understand but lot of parts where i ask me:
    Why do they use this way and what they are doing here and why?

    I didn't do a script excepting the messagebox, because i don't know how to start.
    I am missing explained examples, tutorials for step by step.

    I am not a native english-speaker
    By the way: i did my first coding on the Commodore Plus 4 :-)

    Post edited by Lonesome Cowboy on
  • You probably need to ask specific questions.

  • DAZ has a specific environment.

    What have i to know about daz-functions? How do i find a function that i need for a special problem?
    In the list there are a lot of functions, but i do not in all cases understand how to use them.

    For example:
    i want to write a script that makes all nodes invisible / visible, beginning form the selected one recursive till the end: the shoulder till all fingers or the hip till the foot ...

    What functions / workflow do i need for this and how do i create this?

  • TotteTotte Posts: 13,497

    DAZ has a specific environment.

    What have i to know about daz-functions? How do i find a function that i need for a special problem?
    In the list there are a lot of functions, but i do not in all cases understand how to use them.

    For example:
    i want to write a script that makes all nodes invisible / visible, beginning form the selected one recursive till the end: the shoulder till all fingers or the hip till the foot ...

    What functions / workflow do i need for this and how do i create this?

    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/start

  • thanks. I know this list, but it is quite useless.

    There are ofte no examples how and why to use these functions and sometimes not what they do.

  • You would want to get the selected item (Scene>getPrimarySelection(), though there are also methods to get all seelcted nodes, seelcted figures, and so on - Scene is a global DzScene object).

    Once you have the Primary selection (or whatever list of selected items you prefer) you can use node.getNodeChildren( true ) on it to get an array listing all of the dzNode objects parented to it (getNodeChildren is used to get children, true tells the object to return children-of-children and so on, not just the immediate children). Once you have the list of nodes (selection plus children) use node.setVisible( false ) to hide them. That's using DzNode and DzScene, plus basic control functions.

    As well as the DS 4 docs Totte listed I recommend getting the DS3 docs, which cover all of the objects then available (most of which are still valid): http://docs.daz3d.com/doku.php/public/software/dazstudio/3/start

  • Lonesome CowboyLonesome Cowboy Posts: 153
    edited August 2017

    Thanks Richard,

    i understand what you mean and i see "DzNode : getPrimarySelection() " but i have no idea how to start and to use it.
    i have watched at a lot of dsa-scripts, but they can't help.

    But i have downloaded the file in the link above. I will study it next weeks.
    They seem to be very helpful and there are examples too.
    Unfortunately the examples are not easy to copy because of the line-numbers.

    But it is a step forwards.
    Thank you very much for help.

    Post edited by Lonesome Cowboy on
  • TotteTotte Posts: 13,497

    Thanks Richard,

    i understand what you mean and i see "DzNode : getPrimarySelection() " but i have no idea how to start and to use it.
    i have watched at a lot of dsa-scripts, but they can't help.

    But i have downloaded the file in the link above. I will study it next weeks.
    They seem to be very helpful and there are examples too.
    Unfortunately the examples are not easy to copy because of the line-numbers.

    But it is a step forwards.
    Thank you very much for help.

    Look at the samples then: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/start

     

  • The line numbrs are just for reference, and there is a link to download the file at the top of each code block

    It's Scene.getPrimarySelection, by the way:

    var oItem = Scene.getPrimarySelection();

    wil put the primary seelction, if there is one, in oItem for further work.

  • stitlownstitlown Posts: 276

    Persevere Lonesome C because it is so worth it once you start to see through the fog.  The other useful thing I found was studying some of the simple free scripts - mjcasual's stuff is great.

    // by mCasual/Jacques

    // Copyright (c) 2014 <mCasual/Jacques>

     At some point the scripting structures will "click" for you. 

    The hardest concept I found was the distinction between an object and the values attached to an object.  For my sort of scripts, you can't manipulate an object, but you have to get to the object in order to manipulate the values attached to it.   I made most progress early on by having thousands (well .. maybe 5) of message boxes that displayed what it was that I had just retrived.  And if the result is [Object.object] or something similar it means you've got the object itself and now you have to query (or change)  the values attaching to that object.

    eg

    var mMsg = nWSRot + "\n" + nEuler + "\n" + nDeg + "\n" + nRotOrder ;

    MessageBox.information(mMsg, "My Rotations", "&RockOn");

    Hope that helps

  • TotteTotte Posts: 13,497
    edited August 2017

    I wrote two routines to dump eveything to the console, only way to understamd what happens..

     

     

    // ==========================================
    // logit
    // ==========================================
    function logit(sMessage) {
        if (gDebugMode) {
            debug(sMessage);
            App.flushLogBuffer();
        }
    }

    // ==========================================
    // logarray
    // ==========================================
    function logarray(aArray) {
        if (gDebugMode) {
            logit("# Begin Array dump:");
            for ( var index=0; index<aArray.length; index++) {
                processEvents();
                logit(aArray[index]);
            }
            logit("# End Array dump");
        }
    }

    Post edited by Totte on
  • Richard HaseltineRichard Haseltine Posts: 96,718
    edited August 2017

    I tend to just print( whatever ) which sends it to the console area at the bottom of the IDE pane. (The IDE pane does have a debugger, but I've not used it much.)

    Post edited by Richard Haseltine on
  • stitlownstitlown Posts: 276

    Good tips guys - will use next time I'm pulling my hair out.

  • KitsumoKitsumo Posts: 1,210
    edited August 2017

    I didn't realize this thread came back to life. Thanks for all the useful info, everyone. I'm still trying to wrap my head around how objects work and how they're used in DS.

    So, I've been looking through the samples to see if I can understand what's going on. Can someone tell me if I'm on the right track?

    Singleshot_Timeout.dsa

    // Create a new timer object
    var oTimer = new DzTimer();
    So oTimer is the object being created. DzTimer (and all the other DzStuff) aren't
     actually objects, they're templates for objects that we can create. Is that right? 
    
    // Set the timer to be of the 'run once and stop' variety
    oTimer.singleShot = true;
     
    // Connect the timeout signal on the timer to a function we want to call;
    // an anonymous function in this case, wherein we report state and clean up
    oTimer.timeout.connect( function(){ print( "oTimer.active =", oTimer.active ); oTimer.deleteLater(); } );
     Is this just a function being created without a name? Is it just used this once and then the program erases it?
     So if you did the same thing later in the script (with a totally different function) the two won't interfere
     with each other? I've always been told never create anything without giving it a descriptive name. My whole
     world is upside down now.  :(
    
    // Define timer duration, in milliseconds;
    // also used as a guard for max iterations in a 'busy' loop
    var nTimeout = 1000;
     
    // Start the timer
    oTimer.start( nTimeout );
     
    // Initialize a counter
    var nCount = 0;
     ok, I got all that.
    // While the timer is active, and we haven't exceeded our max
    while( oTimer.active && nCount <= nTimeout ){
    	// Allow the application to keep working; !IMPORTANT!
    	processEvents();
    	// Report state and iteration
    	print( "oTimer.active =", oTimer.active, nCount );
    	// Increment the count
    	nCount += 1;
    }
    I kind of got lost during this part. The timer is started and the variable nCount is initialized. Is the whole
     purpose of this loop to execute once per millisecond? Does processEvents() just tell the processor to wait
     until the next millisecond before continuing the loop? I'm thinking a while loop running on it's own would
     complete way more (or less) than 1000 loops in a second depending on the processor speed and this is a way
     of regulating it.
    
    Richard Hasseltine, thanks for the link to the Daz3 docs. That will help me a lot.
    
    Post edited by Kitsumo on
  • hphoenixhphoenix Posts: 1,335
    Kitsumo said:

    I didn't realize this thread came back to life. Thanks for all the useful info, everyone. I'm still trying to wrap my head around how objects work and how they're used in DS.

    So, I've been looking through the samples to see if I can understand what's going on. Can someone tell me if I'm on the right track?

    Singleshot_Timeout.dsa

    // Create a new timer object
    var oTimer = new DzTimer();
    So oTimer is the object being created. DzTimer (and all the other DzStuff) aren't
     actually objects, they're templates for objects that we can create. Is that right? 
    

    More precisely, DzTimer is a class definition, and you are creating a new instance of that class as an object, calling it's default constructor, and assigning the result to oTimer.  But you can definitely look at it as you described....but they aren't really templates (that's a very specific term in programming.)

     

    // Set the timer to be of the 'run once and stop' variety
    oTimer.singleShot = true;
     
    // Connect the timeout signal on the timer to a function we want to call;
    // an anonymous function in this case, wherein we report state and clean up
    oTimer.timeout.connect( function(){ print( "oTimer.active =", oTimer.active ); oTimer.deleteLater(); } );
     Is this just a function being created without a name? Is it just used this once and then the program erases it?
     So if you did the same thing later in the script (with a totally different function) the two won't interfere
     with each other? I've always been told never create anything without giving it a descriptive name. My whole
     world is upside down now.  :(
    

    This is called an anonymous function.  They exist only within the defining scope, IIRC.  In this case, when the timeout occurs, the function to be called will be executed, but since it is anonymous, there is no way to access it outside that scope.  It doesn't get erased or go out of scope once used, as it was defined in the global scope.  It will persist until the script exits.  Also, since it is anonymous, it only has access to its own local variables, and global variables.

    No, using other anonymous functions within the same script won't interfere with each other.  They get assigned internal names when they are first referenced, and they're unique.  So you can use as many as you like.

    It's a bad practice (and in many languages, not possible) in most languages, but necessary in some.  And it is often more efficient.  However, you could just as easily define a named function, and pass that instead.

     

    Kitsumo said:

     

    // Define timer duration, in milliseconds;
    // also used as a guard for max iterations in a 'busy' loop
    var nTimeout = 1000;
     
    // Start the timer
    oTimer.start( nTimeout );
     
    // Initialize a counter
    var nCount = 0;
     ok, I got all that.
    // While the timer is active, and we haven't exceeded our max
    while( oTimer.active && nCount <= nTimeout ){
    	// Allow the application to keep working; !IMPORTANT!
    	processEvents();
    	// Report state and iteration
    	print( "oTimer.active =", oTimer.active, nCount );
    	// Increment the count
    	nCount += 1;
    }
    I kind of got lost during this part. The timer is started and the variable nCount is initialized. Is the whole
     purpose of this loop to execute once per millisecond? Does processEvents() just tell the processor to wait
     until the next millisecond before continuing the loop? I'm thinking a while loop running on it's own would
     complete way more (or less) than 1000 loops in a second depending on the processor speed and this is a way
     of regulating it.
    

    The timer is started, and will (in 1000ms) call the connected function (the anonymous function mentioned earlier.  Since we set singleShot to TRUE, it will only fire ONCE.

    The while loop will execute while the timer is active.  When it fires, and completes calling it's callback function, since it is singleShot, it will set active to false.  So it should only fire once, then the script will end.  Until then, the loop will repeatedly print it's messages (as fast as it can) while still yeilding activity to the main program (DAZ Studio) to handle things (that's what processEvents() does).

    This particular case is a bit tricky....since the timeout is 1000 ms, and the counter will increment in the loop pretty quick.  It could be non-deterministic....meaning that depending on your particular computer, you might finish 1000 iterations through the loop before 1000ms elapse, but on another you might not.  The print() function only outputs to the ScriptIDE pane, so it won't even be visible unless you are running it in there.  But in there you'd see it printing a bunch of lines counting upward.....it will either get to 1000 counts and exit, or the timer will fire, and will then go inactive, causing the loop to exit when it checks the active value again.

    I'm not sure about the deleteLater() method being called in the anonymous callback function.....it's not mentioned in the documentation.  Someone else will have to comment on that!

     

  • KitsumoKitsumo Posts: 1,210

    Excellent. Thanks. I don't know where I picked up that template term. I'll look through some more examples now that it's starting to make sense.

     

  • TotteTotte Posts: 13,497

    Just wanted to add my latest "must-have" debug function

    // ==========================================

    // logitobj

    // ==========================================

    function logitobj(oObject) {

    if (gDebugMode) {

    debug(JSON.stringify(oObject));

    App.flushLogBuffer();

    }

    }

     


  • Hi,

    meanwhile i know some basics of the daz scripting, but i am still missing an explaining of the single functions and what they do.
    i have a tutorial from Winterbrose and it's great but it doesn't answer all my questions.

    I want to go recursive on a selected figure from the selected point on till the end (for example: i select the left shoulder and it shold go till to the fingers)

    I want to change the follwing things:

    - hide and show
    - look and unlook (x, y or z or all)

    I can't find a description for manipulating all of the selected nodes on this way.

    On http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/start
    there are some little parts i understand but the most i don't understand and i don't need.

    I started with
    var oNode = Scene.getPrimarySelection()
    and then i used
    var nChildNodes = oNode.getNumNodeChildren()
    and then i go this way:
    for (i = 0; i< nChildNodes; i++)
    {
    ...
    but here my ideas and knowledge left me behind ;-)

    Things like
    print (getNodeNames( oNode.getNodeChild( i ));
    don't work

    thanks for help

  • TotteTotte Posts: 13,497

    Hi,

    take a look at this one for hiding XZY property sliders of bones.

     

     

    dsa
    dsa
    BWC-Lock-and-Hide.dsa
    2K
  • Lonesome CowboyLonesome Cowboy Posts: 153
    edited October 2019

    Thanks. This helped me a bit. I modifyed the script in this way you see below (there is only the hide-function active),
    but it works in a strange way:

    The bones are hidden in THE SCENE-TAB, not in the Viewport !!!!

    So i think it is better not to use the skeletton, but the nodes:
    var oNode = Scene.getSelectedNode( 0 );

    but i don't know how to work with, how to go through the tree and set the hidden-property here
     

     

    // DAZ Studio version 4.12.0.85 filetype DAZ Script

    function lockproperty(property)
    {
    property.lock(true);
    }

    function hideproperty(property)
    {
    property.setHidden(true);
    }

    function lock_tree(objectNode)
    {
    var oSkel = objectNode.getSkeleton();

    if (oSkel == null)
    {
         MessageBox.warning( "This is not an actor with bones!!", "Problem", "&Ok, i correct!", "" );
         return;
    }

    var bones = oSkel.getAllBones();

    // Loop every bone an lock_and_hide

    for (var i=0; i<bones.length; i++)
    {

    var node = bones[i];

    lockproperty(node);

    }

    }

    function hide_tree(objectNode)
    {
    var oSkel = objectNode.getSkeleton();

    if (oSkel == null)

    {

    MessageBox.warning( "This is not an actor with bones!!", "Problem", "&Ok, i correct!", "" );

    return;

    }

    var bones = oSkel.getAllBones();

    // Loop every bone an lock_and_hide

    for (var i=0; i<bones.length; i++)

    {

    var node = bones[i];

    hideproperty(node);

    }

    }

     

    var oNode = Scene.getPrimarySelection()

    if (oNode)

    {

    var oNode = Scene.getSelectedNode( 0 );

    hide_tree(oNode);
    }

    else

    {

    MessageBox.critical( "You must selecct a node in the Scene tab! ", "OOPS!", "&I will do it");

    }

     

    The script should work from selectedNode on till the end of the bone-tree (fingers, toes, ...)

    Post edited by Lonesome Cowboy on
  • TotteTotte Posts: 13,497

    Isn't that just a refresh issue? 

  • Lonesome CowboyLonesome Cowboy Posts: 153
    edited October 2019

    i think not.

    When i set the setHidden to false, the bones are back.

    Otherwiese ... hmmm... i don't know how and where to find them ... ;-)

     

    But we are on the right way, but every solution gives a new question ...

    Post edited by Lonesome Cowboy on
  • ChaosDrgnChaosDrgn Posts: 18
    I know this is an old thread and probably outdated. This may also be common knowledge now. As a reminder, ActionScript for Adobe Flash was an OOP ECMAScript based language. While there are differences of course between softwares with the idea of timelines, scenes, animation, etc it may be a little better help than straight JavaScript for web.
Sign In or Register to comment.