Simple Script for Scene Arrangement Information Passing?

Alright, bear with me because I only know enough about programming to (hopefully) ask the right questions.

Let us assume that, thanks to the power of the Daz Bridges, we have the Geometry of a Room (such as a broomcloset) and its Contents (which are its Children, and could be things like a mop and a broom) in two different programs. For example, Daz and Blender. They are, at the moment, arranged identically. That means that all of their Rotation, Scale, and Translation Values (which I’ll call RST Values from now on for brevity) are essentially the same. (I say “essentially” because the two programs could have differences of opinion on which way the XYZ planes go, unit sizes, etc. These differences are not enough to prevent reproducing the scene’s arrangement and are possible to account for.)

Now, suppose I were to change some of the RST Values in one program and wanted to replicate the Effective Changes (Effective, not actual, due to the previously mentioned Differences of Opinion) in the other program. Would the way to do this be something like:

1. Have user select the Parent Object (meaning the Room) in the program that was used to make the changes

2. Have a script record the Names and RST Values of the Room and its Children, and put that information into a txt file

3. Have the user launch a script in the Program that did not make the changes (meaning the Receiving Program)

4. Script (in the Receiving Program) asks the User to select the txt file, then the Target Object (meaning, in this case, the Copy of the Room in the Receiving Program) to apply the RST Values recorded in the txt file to

5. Script double checks that the names of the Selected Object its Children match what was recorded in the txt file (or at least checks if the hierarchy structure matches) and proceeds if they do

6. Script, making sure to account for the Differences of Opinion, applies the corresponding RST Values recorded in the txt file to the Selected Object and its Children. This (hopefully) achieves the goal of making the arrangement of the Rooms match again.

Is this set of instructions performable using Daz's Scripting Language (for the Daz Part of it, I mean. The other programs will require the use of whatever they have. Like Blender using Python for example.)

Comments

  • cridgitcridgit Posts: 1,757
    edited May 2022

    Redacted

    Post edited by cridgit on
  • PraxisPraxis Posts: 252

    cridgit said:

    Firstly use JSON not CSV or TXT.

    Secondly, try this script. It does import/export using JSON for the selected object and all its children (ignoring bones).

    // DAZ Studio version 4.15 filetype DAZ Script// ************************************************************// UI// ************************************************************function RTSTransferDialog(selectedNode, filename, handler){	this.selectedNode = selectedNode;	this.filename = filename;	this.handler = handler;};RTSTransferDialog.prototype.show = function(){	// Check inputs	if (!this.selectedNode || !this.filename || !this.handler)	{		MessageBox.information("Unknown error.", "Error", "&OK" );		return;	}	// Create dialog	this.dialog = new DzBasicDialog();	this.dialog.caption = "Transfer RTS";	this.dialog.maxHeight = this.dialog.minHeight;	this.dialog.showAcceptButton(false);	this.dialog.showHelpButton(false);		// Setup widgets	var infoGroup = new DzHButtonGroup(this.dialog);	infoGroup.title = "Filename:";	this.dialog.addWidget(infoGroup);		var filenameEdit = new DzLineEdit(infoGroup);		filenameEdit.readOnly = true;		filenameEdit.text = this.filename;		filenameEdit.minWidth = 200;	var buttonGroup = new DzHButtonGroup(this.dialog);	this.dialog.addWidget(buttonGroup);		var importButton = new DzPushButton(buttonGroup);		importButton.text = "Import";		connect(importButton, "clicked()", this, "onImportClick()");			var exportButton = new DzPushButton(buttonGroup);		exportButton.text = "Export";		connect(exportButton, "clicked()", this, "onExportClick()");		// Show dialog:	this.dialog.exec();};RTSTransferDialog.prototype.onImportClick = function(){	this.handler.do_import(this.filename, this.selectedNode);	this.dialog.close();};RTSTransferDialog.prototype.onExportClick = function(){	this.handler.do_export(this.selectedNode, this.filename);	this.dialog.close();};// ************************************************************// Controller// ************************************************************function RTSTransferHandler(){};RTSTransferHandler.prototype.do_import = function(filename, selectedNode){	// Check inputs	if (!filename || !selectedNode)	{		MessageBox.information("Unknown error.", "Error", "&OK" );		return;	}	// Import data from JSON file	var file = new DzFile(filename);	if (!file.open(file.ReadOnly))	{		MessageBox.information("Cannot open file %1".arg(filename), "Error", "&OK" );		return;	}	var imported_data = JSON.parse(file.read());	file.close();	// Apply RTS to each node in imported data	for (name in imported_data)	{		// Find node with this name		var node = Scene.findNode(name);		if (!node)		{			print("Cannot find node %1 in imported data".arg(name));			continue;		}		// Apply rotation to this node		node.getXRotControl().setValue(imported_data[name].x_rot);		node.getYRotControl().setValue(imported_data[name].y_rot);		node.getZRotControl().setValue(imported_data[name].z_rot);		// Apply translation to this node		node.getXPosControl().setValue(imported_data[name].x_pos);		node.getYPosControl().setValue(imported_data[name].y_pos);		node.getZPosControl().setValue(imported_data[name].z_pos);		// Apply scale to this node		node.getScaleControl().setValue(imported_data[name].w_scale);		node.getXScaleControl().setValue(imported_data[name].x_scale);		node.getYScaleControl().setValue(imported_data[name].y_scale);		node.getZScaleControl().setValue(imported_data[name].z_scale);	}};RTSTransferHandler.prototype.do_export = function(selectedNode, filename){	// Check inputs	if (!selectedNode || !filename)	{		MessageBox.information("Unknown error.", "Error", "&OK" );		return;	}	// Create export data container	export_data = {};	// Get all nodes in scene	all_nodes = Scene.getNodeList();	// Read RTS from selected node and all its children	for (var i=0; i < all_nodes.length; i++)	{		var node = all_nodes[i];				// Ignore this node if it is not a child of selectedNode (and not selectedNode itself)		if (node != selectedNode && !selectedNode.findNodeChild(node.name, true))			continue;		// Ignore bones (we're only interested in the figure itself)		if (all_nodes[i].className() == "DzBone")			continue;		// Add this node to container		export_data[node.name] = {};		// Read rotation from this node		export_data[node.name].x_rot = node.getXRotControl().getValue();		export_data[node.name].y_rot = node.getYRotControl().getValue();		export_data[node.name].z_rot = node.getZRotControl().getValue();		// Read translation from this node		export_data[node.name].x_pos = node.getXPosControl().getValue();		export_data[node.name].y_pos = node.getYPosControl().getValue();		export_data[node.name].z_pos = node.getZPosControl().getValue();		// Read scale from this node		export_data[node.name].w_scale = node.getScaleControl().getValue();		export_data[node.name].x_scale = node.getXScaleControl().getValue();		export_data[node.name].y_scale = node.getYScaleControl().getValue();		export_data[node.name].z_scale = node.getZScaleControl().getValue();	}	// Export data to JSON file	var file = new DzFile(filename);	if (!file.open(file.WriteOnly | file.Truncate))	{		MessageBox.information("Cannot open file %1".arg(filename), "Error", "&OK" );		return;	}	file.writeLine(JSON.stringify(export_data, null, "    "));	file.close();};// ************************************************************// Main// ************************************************************(function(selectedNode){	// Ensure that a node is selected	if (!selectedNode)	{		MessageBox.information("Select root node.", "Error", "&OK" );		return;	}	// Set default import/export filename	var filename = "%1/%2".arg(App.getTempPath()).arg("YOURFILENAME.JSON");	// Create handler to handle the import/export	var handler = new RTSTransferHandler();	// Create and show dialog	var dialog = new RTSTransferDialog(selectedNode, filename, handler);	dialog.show();})(Scene.getPrimarySelection());

     

    Very nice!

    Thank you.smiley

  • cridgitcridgit Posts: 1,757
    edited May 2022

    Redacted

    Post edited by cridgit on
  • edited June 2021

    Wow! That is amazing. Thank you so much! I'm very glad I did not have to write that because that would have taken me a long time to get something anywhere near that. Definitely way longer than I would have expected. Solid advice about the JSONs, I'd forgotten about those (though I'd only barely learned about them from making a very basic mod for a video game once).

    Question: Why are bones ignored? Is there a technical reason to do that or was it just simpler or maybe something like "not every program would have them" or...? (Forgive my ignorance, I'm still learning Daz too).

    Post edited by ZaeZodTheToonCrafter on
  • cridgitcridgit Posts: 1,757
    edited May 2022

    Redacted

    Post edited by cridgit on
  • edited June 2021

    Not working with bones should be fine then. Thank you again! Now I just need to figure out how to make versions of the script for Blender, Unity, and/or Unreal. With the power to send the RST values back and forth, it will be possible use one (or more, haven't really picked favorites) of those programs' VR controls to arrange a Daz scene. (Nothing against Daz's controls, in fact I like Daz's GUI a lot better than those other programs so far, it's just that when it comes to arranging a room it just feels more intuitive to use my hands.) Hopefully I'll be able to translate your script for the other programs to use.

    Edit: I think I'll ask in the Blender, Unity, and Unreal parts of the Daz forum first though.

     

    Edit Edit: Also, sorry if I'm very slow to respond, irl stuff is making it hard to devote time to this.

    Post edited by ZaeZodTheToonCrafter on
Sign In or Register to comment.