Hi, once again I started a script project to solve a specific issue I had. Read How to Get PowerPose to Work with Genesis 3?
I want to create a simple PowerPose template but I'm too lazy to write all the boring stuff myself even with copy-paste this takes some time and is prone to typos. So yesterday I started to write this script that generates all these lines for me that look like HTML tags based on the selected figure to have at least something to work with while creating the actual tamplate.
For me it is meant to be used to create a face rig template for genesis 3 figures and there are 64 control points in the template that need to get defined for PowerPose with a bone label and a position on the pane.
Here is my first version that does at least something usable. I can imagine this script could also serve others that want to create PowerPose templates for their custom figures. Maybe I should add some kind exclude bones check so you can run it from the root node of the figure without having everything included.
It generated 640 lines of PowerPose template code in a few milliseconds and includes all control points that I wanted for my PowerPose template.
It is far from beeing perfect and I need to find some other way to positioning the control points currently that isn't working at all. I post this script anyway even if I dircracing myself for not getting such a simple thing like one dimensinal offsets to work. I will have a look at it again after some sleep.
But that's why I post this becasue I need some help getting it right. So please can someone have a look and find out why I have commas in a few lines of the string / array output in the console. Must be some issue with the array index or the line break "\n" I've added everywhere. I wonder why I can print out the aTemplate array without joining it. Also I need to test if I have to choose inverted control settings depending on if its a left or right side bone.
I hope you don't mind that I borrowed the upper part of the script from the script example "Adjust Rigging to Shape"
That example just got the right checks and error messages for working with figure bones. I've included the Creative Commons Attribution 3.0 information in the header comment and included infromation that this is a modification of the original script example.
Download link: GeneratePowerPoseTemplateFile.dsa 8K
Screenshots of the console output.
// DAZ Studio version 4.10.0.123 filetype DAZ Script
/**********************************************************************
Copyright (C) 2002-2019 Daz 3D, Inc. All Rights Reserved.
Script code: MODIFIED! No warranty of any kind.
This script is provided as part of the >> Daz Script Developer Discussion
Creative Commons Attribution 3.0 Unported (CC BY 3.0)
- http://creativecommons.org/licenses/by/3.0
To contact Daz 3D or for more information about Daz Script visit the
Daz 3D website:
- http://www.daz3d.com
**********************************************************************
GeneratePowerPoseTemplateFile.dsa
**********************************************************************
- select a genesis 3 or 8 figure
- the script searches for two bones labeled "Upper/Lower Face Rig"
- based on the child bones the script will then print out a few informations
- finaly the PowerPose template code gets printed to the Script IDE console
This script includes parts of the Scripting example:
Adjust Rigging to Shape
Source:
http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/nodes/adjust_rigging_to_shape/start
created: 2019-06-20 by Syrus_Dante
edited: 2019-06-21 by Syrus_Dante
P.S. Sorry I was lazy again I just copied the upper part of the script example because it got all checks and error messages that I wanted.
*********************************************************************/
(function( oNode ){
/*********************************************************************/
// 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;
};
/*********************************************************************/
// Define message components
var sTitle = text("Resource Error");
var sMessage = text("This script requires version 4.9.3.93 or newer.");
var sOk = text("&OK");
// If the application is less than 4.9.3.93
if( App.version64 < 0x000400090003005d ){
// Inform the user
MessageBox.information( sMessage, sTitle, sOk );
// We're done...
return;
}
// Initialize
var oFigure = undefined;
// If we have a bone
if( oNode.inherits( "DzBone" ) ){
// Get its skeleton
oFigure = oNode.getSkeleton();
// If we have a figure
} else if( oNode.inherits( "DzFigure" ) ){
// We have what we want
oFigure = oNode;
}
// If we don't have a weight mapped figure
if( !oFigure || !oFigure.inherits( "DzFigure" ) ){
// Define message components
sTitle = text("Selection Error");
sMessage = text("This script requires a weight mapped figure to be selected.");
// Inform the user
MessageBox.information( sMessage, sTitle, sOk );
// We're done...
return;
}
// Get the object
var oObject = oFigure.getObject();
// If the node doesn't have an object
if( !oObject ){
// Define message components
sTitle = text("Selection Error Object");
sMessage = text("This script requires an object with geometry to be selected.");
// Inform the user
MessageBox.information( sMessage, sTitle, sOk );
// We're done...
return;
}
/*********************************************************************
Start Script Modification
*********************************************************************/
var aNodes = oFigure.getAllBones ();
var sLabel = oFigure.getLabel();
var aChildBones = [];
var nBkrndResX = 480;
var nBkrndResY = 720;
var nXoffset = 0;
var nXoffsetLeft = 10; //offsets are related to the x/y pixel coordinates on the backround image
var nXoffsetRight = 10;
var nYoffset = 265; //I just gave some values here so the points don't end up all on the same spot
var sText;
var aTemplate = [""]; //the actual template text that can later get written do a DSX file
//you can choose which controls you want to have in the lower PowerPose pane - currently only sControlSet01 is used
var sControlSet01 =
"\t<lmb_horiz_prop>ytran</lmb_horiz_prop>\n"
+ "\t<lmb_vert_prop>xtran</lmb_vert_prop>\n"
+ "\t<rmb_horiz_prop>zrot</rmb_horiz_prop>\n"
+ "\t<rmb_horiz_sign>neg</rmb_horiz_sign>\n"
+ "\t<rmb_vert_prop>xrot</rmb_vert_prop>\n";
var sControlSet02 =
"\t<lmb_horiz_prop>ytran</lmb_horiz_prop>\n"
+ "\t<lmb_vert_prop>xtran</lmb_vert_prop>\n"
+ "\t<rmb_horiz_prop>zrot</rmb_horiz_prop>\n"
+ "\t<rmb_horiz_sign>neg</rmb_horiz_sign>\n"
+ "\t<rmb_vert_prop>xrot</rmb_vert_prop>\n";
print("The selected figure [%1] got that many bones: [%2]"
.arg(sLabel)
.arg(aNodes.length));
/* this was for testing and was printing out all bones at once
for ( var n = 0 ; n < aNodes.length ; n++ ) {
oObject = aNodes[n];
sLabel = aNodes[n].getLabel();
print("Node Nr: %1 Label: %2"
.arg(n+1)
.arg(sLabel));
}
*/
/*********************************************************************
generateTemplate constructs a strig based on the bone label you give and the child bones on the figure
*********************************************************************/
function generateTemplate( sStartWithBoneLabel ) {
var oBone = oFigure.findBoneByLabel(sStartWithBoneLabel);
print("\n\nSearch for a bone with the label: %1" .arg(sStartWithBoneLabel));
if( !oBone ){
print("> Didn't found a bone with the label '%1'!\nThe selected figure should be Genesis 3 or 8."
.arg(sStartWithBoneLabel));
return null; //finished with error
}else{
print("> found '%1' - it includes [%2] child bones.\n"
.arg(sStartWithBoneLabel)
.arg(oBone.getNumNodeChildren(false)));
aChildBones = oBone.getNodeChildren (false);
for ( var n = 0 ; n < aChildBones.length ; n++ ) {
sLabel = aChildBones[n].getLabel();
print("Node Nr: %1\t\tLabel: %2"
.arg(aTemplate.length)
.arg(sLabel));
//set the x offset by the bone label dosn't work - I will have a look another day
//I want to have all "left" labeled bones on the left side and all "right" labeled on the right side
//sounds simple but I have my issues with getting it right
if(sLabel.search("Left") != -1){
//print("> left bone detected");
//if(nXoffset >= -1) {nXoffset*=-1;} //Invert number if not already negative
nXoffset = ((nXoffsetLeft -= 10) + (nBkrndResX / 2));
}
if(sLabel.search("Right") != -1){
//print("> right bone detected");
//if(nXoffset <= -1) {nXoffset*=-1;} //Invert number if not already positive
nXoffset = ((nXoffsetRight += 10) + (nBkrndResX / 2));
}
if((sLabel.search("Middle") != -1)
|| (sLabel.search("Center") != -1)
|| (sLabel.search("Nose") != -1)){
//print("> middle bone detected");
nXoffset = nBkrndResX / 2;
}
aTemplate[aTemplate.length ++ ] =
("<node_data>\n"
+ "\t<x>%1</x>\n"
+ "\t<y>%2</y>\n"
+ "\t<node_label>%3</node_label>\n"
+ "%4"
+ "</node_data>\n")
// .arg(nXoffset += 10) // add increment of 10
.arg(nXoffset)
.arg(nYoffset)
.arg(sLabel)
.arg(sControlSet01);
}
} return true; //finished with success
}
if( generateTemplate("Upper Face Rig")){
nYoffset += 40;
}else{ return null; }
if( generateTemplate("Lower Face Rig")){
}else{ return null; }
/* obsolete loop? the aTemplate array gets printed out anyway
var sTemplate;
for (var i = 0; i < aTemplate.length; i++){
sTemplate = aTemplate[i].join ( "\n" );
}
*/
print("\n\nThe generated PowerPose template:\n\n%1"
.arg(aTemplate));
// Finalize the function and invoke
})( Scene.getPrimarySelection() );