User Tools

Site Tools


Post-Load View Proxy Create

Summary

Below is an example demonstrating how you can create proxy nodes in the scene for each of the predefined view cameras, create properties on the proxy nodes that correspond with properties on the view cameras and link the properties on the view cameras to the corresponding properties on the proxy nodes. The example also demonstrates how to embed post-load data on each proxy node and cause a script to be executed after the node has been loaded into the scene in order to re-establish the links between the properties which are not otherwise saved.

See Also: Post-Load View Proxy Link Properties

API Areas of Interest

Example

Post_Load_View_Proxy_Create.dsa
// Define an anonymous function;
// serves as our main loop,
// limits the scope of variables
(function(){
 
	/*********************************************************************/
	// String : A function for retrieving a translation if one exists
	function text( sText )
	{
		// If the version of the application supports qsTr()
		if( typeof( qsTr ) != "undefined" ){
			// Return the translated (if any) text
			return qsTr( sText );
		}
 
		// Return the original text
		return sText;
	};
 
	/*********************************************************************/
	// String : A function for finding an absolute file path of a relative one
	function findAbsContentFilePath( sRelFilePath )
	{
		// If the relative path is empty
		if( sRelFilePath.isEmpty() ){
			// We're done...
			return "";
		}
 
		// Get the content manager
		var oContentMgr = App.getContentMgr();
 
		// Declare working variable
		var sFilePath;
 
		// Initialize
		var bHasAllEnums = (App.version64 >= 0x000400090000002e);//4.9.0.46
		var nDirType = DzContentMgr.AllDirs;
 
		// Get the import manager
		var oImportMgr = App.getImportMgr();
		// If the file type is imported
		if( oImportMgr.findImporter( sRelFilePath ) ){
			// If the version does not provide all enumerated values
			if( !bHasAllEnums ){
				// Update the directory type
				nDirType = DzContentMgr.PoserDirs |
							DzContentMgr.ImportDirs |
							0x20; //DzContentMgr.CloudDB
			// Otherwise
			} else {
				// Update the directory type
				nDirType = DzContentMgr.PoserDirs |
							DzContentMgr.ImportDirs |
							DzContentMgr.CloudDB;
			}
		// If the file type is native
		} else {
			// If the version does not provide all enumerated values
			if( !bHasAllEnums ){
				// Update the directory type
				nDirType = DzContentMgr.NativeDirs |
							0x20; //DzContentMgr.CloudDB
			// Otherwise
			} else {
				// Update the directory type
				nDirType = DzContentMgr.NativeDirs |
							DzContentMgr.CloudDB;
			}
		}
 
		// Return the path
		return oContentMgr.findFile( sRelFilePath, nDirType );
	};
 
	/*********************************************************************/
	// String : A function for retrieving the name of the vendor
	function getVendorName( sOverride )
	{
		// Set the vendor to the registered author
		var sVendor = App.getCurrentAuthor().name;
		// If a name was specified
		if( !sOverride.isEmpty() ){
			// Use the specified name
			sVendor = sOverride;
		}
 
		// If we still don't have a name
		if( sVendor.isEmpty() ){
			// Use a default
			sVendor = "Vendor Name";
		}
 
		// Return the vendor name
		return sVendor;
	};
 
	/*********************************************************************/
	// String : A function for retrieving a name for a product
	function getProductName( sDefault )
	{
		// Initialize
		var sProductName = "Product Name";
 
		// Create a basic dialog
		var wDlg = new DzBasicDialog();
		wDlg.caption = text( sProductName );
 
		// Add a label
		var wLbl = new DzLabel( wDlg );
		wLbl.text = text( sProductName ) + ":";
		wDlg.addWidget( wLbl );
 
		// Add a line edit
		var wNameLEdit = new DzLineEdit( wDlg );
		wNameLEdit.text = sDefault;
		wDlg.addWidget( wNameLEdit );
 
		// Get the wrapped widget
		var oDlg = wDlg.getWidget();
 
		// Set the object name of the wrapped widget;
		// this is used for recording position and size
		oDlg.objectName = sProductName.replace( / /g, "" );
 
		// Get the minimum height
		var sizeHint = oDlg.minimumSizeHint;
		var nHeight = sizeHint.height;
 
		// Set the fixed height to the minimum
		wDlg.setFixedHeight( nHeight );		
 
		// If the user didn't cancel the dialog
		if( wDlg.exec() ){
			// Get the name specified
			var sUserInput = wNameLEdit.text;
			// If the input is valid
			if( !sUserInput.isEmpty() ){
				// Update the product name
				sProductName = sUserInput;
			}
		}
 
		// Return the product name
		return sProductName;
	};
 
	/*********************************************************************/
	// void : A function for copying the attribute of one property to another
	function copyPropertyAttributes( oSrcProperty, oTgtProperty, oSettings )
	{
		// Get the attributes of the source property
		oSrcProperty.getAttributes( oSettings );
 
		// Set the attributes of the target property
		oTgtProperty.setAttributes( oSettings );
 
		// Clean up
		oSettings.clear();
	};
 
	/*********************************************************************/
	// void : A function for creating a one to one link between properties
	function linkProperties( oSlaveProperty, oMasterProperty )
	{
		// Link the slave property to the master property
		oSlaveProperty.linkTo( oMasterProperty );
	};
 
	/*********************************************************************/
	// String : A function for establishing the post-load for linking properties
	function setLinkPropertiesPostLoad( oProxyElement, oTargetElement, aProperties )
	{
		// Get the name of the target element
		var sTargetName = oTargetElement.name;
 
		// Define a unique name for our data item
		var sDataName = String("%1__%2__%3__LinkPropertiesPostLoad")
					.arg( m_sVendorName )
					.arg( m_sProductName )
					.arg( sTargetName );
 
		// Get our data item
		var oDataItem = oProxyElement.findDataItem( sDataName );
 
		// If we didn't find our data item
		if( !oDataItem ){
			// Create our data item; we want it to be saved with the element
			oDataItem = new DzSimpleElementScriptData( sDataName, true );
 
			// Set the path to our script
			oDataItem.setScriptFilePath( m_sScriptRelPath );
 
			// Add the data item to the element
			oProxyElement.addDataItem( oDataItem );
		}
 
		// Get the settings for the data item
		var oSettings = oDataItem.getSettings();
 
		// Assign key/value pairs
		oSettings.setStringValue( "vendor", m_sVendorName );
		oSettings.setStringValue( "product", m_sProductName );
		oSettings.setStringValue( "target", sTargetName );
 
		// Get the properties settings
		var oPropertySettings = oSettings.getSettingsValue( "properties" );
		// If the properties settings does not exist
		if( !oPropertySettings ){
			// Create the properties settings
			oPropertySettings = new DzSettings();
		// If the properties settings does exist
		} else {
			// Clear the list of properties
			oPropertySettings.clear();
		}
 
		// Declare working variables
		var sProperty;
 
		// Iterate over the property names
		for( var i = 0, nProps = aProperties.length; i < nProps; i += 1 ){
			// Get the 'current' property name
			sProperty = aProperties[ i ];
 
			// Add the setting for the property
			oPropertySettings.setBoolValue( sProperty, true );
		}
 
		// Assign key/value pairs
		oSettings.setSettingsValue( "properties", oPropertySettings );
	};
 
	/*********************************************************************/
	// Get the vendor name
	var m_sVendorName = getVendorName( "" );
 
	// Get the product name
	var m_sProductName = getProductName( "" );
 
	// Define the post-load script name
	var m_sScriptName = "Post_Load_View_Proxy_Link_Properties";
 
	// Define the script extension
	var sExtension = "dsa";
 
	// Construct the relative path of the post-load script;
	// by placing the script within the data folder, under a
	// vendor/product/item name for organizational purposes,
	// you have prepared it for product-ization and for being
	// installed via Daz Connect or Daz Install Manager
	var m_sScriptRelPath = String("data/%1/%2/%3.%4")
				.arg( m_sVendorName )
				.arg( m_sProductName )
				.arg( m_sScriptName )
				.arg( sExtension );
 
	// Find the post-load script within the content management system
	var sScriptAbsPath = findAbsContentFilePath( m_sScriptRelPath );
	// If the script could not be found
	if( sScriptAbsPath.isEmpty() ){
		// Define text variables for the message
		var sTitle = text( "File Not Found" );
		var sMessage = text( "The '%1' file could not be found." )
				.arg( m_sScriptRelPath );
		var sButton = text( "&OK" );
		// Inform the user
		MessageBox.information( sMessage, sTitle, sButton );
 
		// We're done...
		return;
	}
 
	// Define the list of properties on the
	// target node to create a proxy for
	var aPropertyNames = [
		"XTranslate",
		"YTranslate",
		"ZTranslate",
		"XRotate",
		"YRotate",
		"ZRotate",
		"Perspective",
		"Frame Width",
		"Focal Length",
		"DOF",
		"Depth of Field",
		"Aperature"
	];
 
	// Declare working variables
	var oCamera, oProxyNode;
	var oCameraProperty, oProxyProperty;
	var sProxyName, sProxyLabel;
	var aCameraProperties, aLinkProperties;
 
	// Create a settings object for copying property attributes
	var oSettings = new DzPropertySettings();
 
	// Get the viewport manager
	var oViewportMgr = MainWindow.getViewportMgr();
 
	// Get the number of view cameras
	var nCameras = oViewportMgr.getNumViewCameras();
 
	// Iterate over all view cameras
	for( var i = 0; i < nCameras; i += 1 ){
		// Get the 'current' view camera
		oCamera = oViewportMgr.getViewCamera( i );
 
		// Construct the proxy node name
		sProxyName = String("%1Proxy").arg( oCamera.name );
		// Construct the proxy node label
		sProxyLabel = String("%1 Proxy").arg( oCamera.getLabel() );
 
		// Find the proxy node in the scene
		oProxyNode = Scene.findNode( sProxyName );
		// If the proxy was not found
		if( !oProxyNode ){
			// Create a new Null node
			oProxyNode = new DzNode();
			// Set the name of the proxy
			oProxyNode.setName( sProxyName );
			// Set the label of the proxy
			oProxyNode.setLabel( sProxyLabel );
			// Add the node to the scene
			Scene.addNode( oProxyNode );
		}
 
		// Copy values of node properties
		oProxyNode.copyFrom( oCamera );
 
		// Initialize a list of properties
		aLinkProperties = [];
 
		// Get the properties on the camera
		aCameraProperties = oCamera.getPropertyList();
		// Iterate over the properties
		for( var j = 0; j < aCameraProperties.length; j += 1 ){
			// Get the 'current' camera property
			oCameraProperty = aCameraProperties[ j ];
 
			// If the name of the property is not in our list
			if( aPropertyNames.indexOf( oCameraProperty.name ) < 0 ){
				// Next!!
				continue;
			}
 
			// Attempt to find the property on the proxy node
			oProxyProperty = oProxyNode.findProperty( oCameraProperty.name );
			// If the property was not found
			if( !oProxyProperty ){
				// Duplicate the property
				oProxyProperty = oCameraProperty.propertyDuplicate();
				// Add the property to the proxy node
				oProxyNode.addProperty( oProxyProperty );
			}
 
			// Copy the setup of the camera property to the proxy property
			copyPropertyAttributes( oCameraProperty, oProxyProperty, oSettings );
 
			// If the property is numeric
			if( oCameraProperty.inherits( "DzNumericProperty" ) ){
				// Link the camera property to the proxy property
				linkProperties( oCameraProperty, oProxyProperty );
 
				// If the property is a transform
				if( oCameraProperty.getXYZInterest() != DzNumericProperty.NO_INTEREST ){
					// Linking transform properties causes issues when attempting to
					// animate; when keyframes exist on the proxy node's transforms,
					// viewport navigation appears to stop responding to user input
					// if the playhead is positioned beyond the last keyed frame as
					// a result of the proxy node's property being the 'master' of
					// the link (which forces the view camera's property to mimic
					// its value)
					oProxyProperty.setCanAnimate( false );
				}
 
				// Capture the name of the property
				aLinkProperties.push( oCameraProperty.name );
			}
		}
 
		// If we've linked properties
		if( aLinkProperties.length > 0 ){
			// Set/Create the post-load that will re-establish the links
			setLinkPropertiesPostLoad( oProxyNode, oCamera, aLinkProperties );
		}
	}
 
// Finalize the function and invoke
})();