Updating an NaN script to 4.9?

macleanmaclean Posts: 2,438

I've been using 'Not A Number' pose presets for a long time now (to move pieces in modular sets). They applythe trans/rot value ad infinitum, so it's not a fixed value - it just keeps adding the same value to the existing one. The ones I have are .dsa files (DS3.1) and although they still work perfectly well, I want to have them conform properly to 4.9 standards. Does anyone know how I would go about it?

Here are 2 samples - a 3.1 script and a 4.9 (a normal fixed value pose preset)

// DAZ Studio version 3.1  filetype DAZ Scriptvar xPos = 170;var yPos = NaN;var zPos = NaN;function moveObject( object ){	if( object == undefined )		return;	if( !isNaN( xPos ) )		object.getXPosControl().setValue( object.getXPosControl().getValue() + xPos );	if( !isNaN( yPos ) )		object.getYPosControl().setValue( object.getYPosControl().getValue() + yPos );	if( !isNaN( zPos ) )		object.getZPosControl().setValue( object.getZPosControl().getValue() + zPos );}beginUndo();for( var i = 0; i < Scene.getNumSelectedNodes(); i++ )moveObject( Scene.getSelectedNode( i ) );acceptUndo( "Move selected object(s)" );

 

{	"file_version" : "0.6.0.0",	"asset_info" : {		"id" : "/Props/Maclean/Interiors/Corridors/Corridors%20Iray/Pose%20Presets/150.duf",		"type" : "preset_pose",		"contributor" : {			"author" : "maclean",			"email" : "",			"website" : "http://www.daz3d.com/maclean";		},		"revision" : "1.0",		"modified" : "2020-09-07T20:14:32Z"	},	"scene" : {		"animations" : [			{				"url" : "name://@selection:?translation/x/value",				"keys" : [ [ 0, -150 ] ]			}		]	}}

TIA

mac

Edit - Can't get 2nd code snippet to Word Wrap - No idea why

Post edited by maclean on

Comments

  • I don't believe that the data in a .duf file can do things like increment a specific value - the .duf file isn't a script, it's just a data structure turned into text (see JSON). A .duf file could call a script, as with the eyelash loading in character presets, but the script itself would not be a new format.

  • I think your script is still the correct way to do this, although I would have written it slightly differently...

    // DAZ Studio version 4.12.1.118 filetype DAZ Script(function(){	// [ xtran, ytran, ztran ]	offsets = [ 170, 0, 0 ];		function updateControlsByOffsets (object) {		functions = [object.getXPosControl, object.getYPosControl, object.getZPosControl];		functions.forEach (function (control, i) { if (offsets[i]) control().setValue (control().getValue() + offsets[i]) });	}	beginUndo();	Scene.getSelectedNodeList().forEach (updateControlsByOffsets);	acceptUndo ("Move");})();

    or if I was doing both translation and rotation at the same time

    // DAZ Studio version 4.12.1.118 filetype DAZ Script(function(){	// [ xtran, ytran, ztran, xrot, yrot, zrot ]	offsets = [ 170, 0, 0, 0, 0, 0 ];		function undoString() {		var tran = offsets.slice (0, 3).some (function (e) { return e != 0 });		var rot  = offsets.slice (3, 6).some (function (e) { return e != 0 });		return (tran ? "Move" : "") + ((tran && rot) ? " / " : "") + (rot ? "Rotate" : "");	}	function updateControlsByOffsets (object) {		functions = [object.getXPosControl, object.getYPosControl, object.getZPosControl,		             object.getXRotControl, object.getYRotControl, object.getZRotControl];		functions.forEach (function (control, i) { if (offsets[i]) control().setValue (control().getValue() + offsets[i]) });	}	beginUndo();	Scene.getSelectedNodeList().forEach (updateControlsByOffsets);	acceptUndo (undoString());})();
  • macleanmaclean Posts: 2,438

    Richard,

    Yes, I see what you're saying. I just wasn't sure what the update method would be.

    Omniflux,

    Thanks for that. That's very helpful indeed. I have separate scripts for rotation, visibilty, etc, but I'll convert them to your format (if that's fine by you). Should make them cleaner and clearer. I know Rob likes everything in DS to be up to a certain standard, so I'm up for that.

    Thanks to both of you.

  • Feel free to use.

    Besides being enclosed in an anonymous function to limit the scope of variables (see all current examples in the API reference), I believe your current script is functionally equivalent and not using anything deprecated or recommended against. My method which is only a personal preference, just has less repetition, which I personally find simpler for maintaining consistency when updating and reviewing code.

  • macleanmaclean Posts: 2,438

    Thanks again, Omniflux. I've set it up and everything works fine.

  • macleanmaclean Posts: 2,438

    Omniflex,

    Sorry to be a pest, but is it possible to add Visibility to your version? The problem I ran into is this.

    I made 2 Property Presets (.duf) for Visibility Off/On, which of course work fine. These 2 presets, plus all the others (.dsa) are in a folder along with a Create Toolbar script which creates Custom Actions from all the scripts, then adds them to a new toolbar on the UI. (There's also a Hide Toolbar script). The peculiar thing is that I couldn't get any .duf in the Create Toolbar script to work - only .dsa. So I dug out Visibility scripts from DS3 (.dsa) and they work.

    But........ (Arghhhhh!!!) , every time I use one - Off or On, it adds another entry to Custom Actions. When I looked earlier in Customise, there were 4 of each. LOL.

    There must be some weirdness about the old Visibility code, although its never appeared before now. I'll post it here and maybe you can tell what the issue is?

    // DAZ Studio version 3.1  filetype DAZ Scriptvar nSelectedItems = Scene.getNumSelectedNodes();var n, curNode;function setPropertyNumeric( oProperty, aKeys ){	if( aKeys.length == 1 )	{		oProperty.setValue( aKeys[ 0 ] );		return true;	}	else if( oProperty.canAnimate() )	{		for( var i = 0; i < aKeys.length; i += 2 )		oProperty.setValue( aKeys[ i ] + m_nSTART_TIME, aKeys[ i + 1 ] );		return true;	}	return false;}function setTransformProperty( sPropertyName, aKeys ){	var oProperty;	switch( sPropertyName )	{		default:			break;	}	setPropertyNumeric( oProperty, aKeys );}if( nSelectedItems == 0 )	MessageBox.warning( "This action requires an item within the scene to be selected.", "Selection Error", "&OK", "" );else{	beginUndo();	for( n = 0; n < nSelectedItems; n++ )	{		curNode = Scene.getSelectedNode( n );		if( curNode != undefined )		{			curNode.setVisible( false );		}	}	acceptUndo( "Node preset" );}

    TIA

    mac

  • OmnifluxOmniflux Posts: 377
    edited September 2020

    I believe actions can only be linked to scripts, and presets (and .duf in general) are not scripts, but data.

    If you want, you can load a duf file via a script, for example

    // DAZ Studio version 4.12.1.118 filetype DAZ Script(function (propertiesFileToMerge){	if (Scene.getNumSelectedNodes() == 0)		MessageBox.warning ("This action requires an item within the scene to be selected.", "Selection Error", "&OK", "");	else {		beginUndo();		var oContentMgr = App.getContentMgr();		oContentMgr.openFile (oContentMgr.getAbsolutePath (propertiesFileToMerge, false));		acceptUndo ("Set properties");	}})("/Presets/VisOn.duf");

    I don't like this solution for this problem though, as it is momentarily pops up a loading window and is slower (at least on my system) than just setting the property in the script.

     

    So back to the script method, the code you posted has some extraneous functions which were probably left there by accident. The functional portion of code is as follows

    var nSelectedItems = Scene.getNumSelectedNodes();var n, curNode;if( nSelectedItems == 0 )	MessageBox.warning( "This action requires an item within the scene to be selected.", "Selection Error", "&OK", "" );else{	beginUndo();	for( n = 0; n < nSelectedItems; n++ )	{		curNode = Scene.getSelectedNode( n );		if( curNode != undefined )		{			curNode.setVisible( false );		}	}	acceptUndo( "Node preset" );}

    This is the way I would write this

    // DAZ Studio version 4.12.1.118 filetype DAZ Script(function(){	// true or false	var visible = true;	if (Scene.getNumSelectedNodes() == 0)		MessageBox.warning ("This action requires an item within the scene to be selected.", "Selection Error", "&OK", "");	else {		beginUndo();		Scene.getSelectedNodeList().forEach (function (x) { x.setVisible (visible) });		acceptUndo ("Set visibility");	}})();

     

    The move script we looked at previously does not include a warning if nothing is selected, and this script does. Whether or not it should gets into UX design which I usually try to avoid, but whichever way you go consistency is key to a good experience.

     

    As to the multiple menu entries, nothing in this code should be creating new entries. Are you absolutely sure this is the script you are executing when the new entries are created? I took a look at the toolbar from Room Creator 2, and it appears that the QuickPose Add script decides if a menu entry already exists based on the absolute file path of the action. Place the scripts in a different directory (or same directory in a different runtime) and run it again, and it thinks it's actions are not the same as those in the first directory and you get two of each entry in the RC Toolbar, one pointing to each script in each location.

     

    If you plan to include this toolbar in multiple products, you'll want to make sure that they all point to the same set of scripts, not each to their own set (the end user can still prevent this by installing different products in different runtimes). The creation script could be modified to recognize that the same scripts in different directories are actually the same, but then you have the minor issue that if you uninstall the product whose script you ran to create the toolbar, the actions will be broken unless you recreate the toolbar even though the necessary scripts still exist for the other products. you should consider not placing the actions in script files, but install them in the action directly by setting isFile = false when calling setCustomActionScript.

    Post edited by Omniflux on
  • macleanmaclean Posts: 2,438

    Wow! That was awesome in its detail! Thanks so much!

    I tried your script and used it mutiple times with no new entries at all, so I think something works now that didn't before.

    // DAZ Studio version 4.12.1.118 filetype DAZ Script(function(){	// true or false	var visible = true;	if (Scene.getNumSelectedNodes() == 0)		MessageBox.warning ("This action requires an item within the scene to be selected.", "Selection Error", "&OK", "");	else {		beginUndo();		Scene.getSelectedNodeList().forEach (function (x) { x.setVisible (visible) });		acceptUndo ("Set visibility");	}})()

    Sending you a PM.

Sign In or Register to comment.