After trying the sample provided here, it appears to only save the head pose. How do I save the pose for the entire figure? I tried adding "hip" and "abdomen" to aNames, to not effect.
Question about Save Pose Preset Sample
Select facet by id?
Hello everyone,
Assume I already know the ids of some facets, is there a way to select these facets via script, then I could use addSelectedFacetsToMaterialGroup() function to add them into a material group?
I have found that DzFacetMesh has some functions such as: selectAllFacets(), selectConnectedFacets() and selectFacets(DzFaceGroup *grp), but they don't seem to meet what I need (please correct me if I'm wrong).
Many thanks :)
I Heart Astrogrep
This is probably something most people already have/use, but I managed to go years without realizing it existed :-P I've been using Astrogrep for a few months and it's something I have open all day as I'm working now. So I thought it might be worth sharing with beginning Script developers as it makes life much, much easier :-).
http://astrogrep.sourceforge.net/
For those who haven't used grep search, it's basically a way of searching for text inside files. I use it to quickly find methods and whatnot (obviously, not all of the methods are wrapped in the script, but many are). When you install it, be sure to select the option to add a "Context Menu" option. Navigate to the Daz SDK folder, right-click the Include folder and Search Using Astrogrep. It is freaking awesome. Previously, I was keeping a ton of libraries open in Notepad++ so I could search them, but this gets unwieldy pretty fast.
Anyway, might not be news to anyone, but it's been such a benefit for me, I wanted to share
Script to attach the Base-Color Image Node to the Top-Coat-Color Node
Hello,
I'm sorry, I'm a complete beginner concerning scripting and haven't done anything like that before, but now I really need a solution to quickly attach the Base-Color-Image-Node to the Top-Coat-Color-Node of a material zone. The prop(s) I want to use this method on have hundreds of material zones and it would take ages to do it manually :(
Thank you in advantage!
[half solved] Is it possible to "connect" widgets "incrementally created"?
I'm making a script which should allow me to change for instance some numeric values on specific nodes properties in a scene via an interface. Since the elements in the scene are never the same, with never the same count, the interface I create first reads the scene nodes and stores in an array the interesting properties of each interesting node (node index, name, label, classname, values of given properties, etc, etc).
Then I display all this using widgets which are parented to a main DzVGroupBox using a DzGridLayout in order to organise the widgets display.
The first step of the creation of the interface works perfectly, it is done by a loop on the first array I initially created when collecting nodes (the one gathering the key properties I want to act on).
The worry I have is when I have to "connect" the signals of the edition of the sliders and color widgets to the functions they are supposed to launch. I cannot have them working at all. Depending on the way I wrote the script, either the functions I connect were applied as soon as the script launches "even when there should be no "EditEnd()" signal emitted" - I guess it is because there was a () at the end of the function I call), or they were totally inefficient.
I tested two ways to create the "incremental" widgets:
- first way using an incremental name for the widgets (wDialName = "wDial"+k where k is the scene index increment, followed by wDialName = new DzFloatSlider(wMainGroup).
- and the second way using an Array including the widgets aWidget[k] = new DzFloatSlider(wMainGroup).
In both cases the widget creation, initialisation (to current value for nodes in the scene), and display in the interface works fine, but the connection fails. Yet there is no error or warning in the console. When I debug, I see no particular issue neither.
This is why I come here to ask the question, is it possible, when widgets are created with loops (or in arrays) method to "connect" them afterwards? Is there a special way to do that ? I also had a look at the QtScript documentation, but I did not found any page about this specific case. So either I have not found out yet how to do this, or it is not possible.
How to detect that a DzDialog is about to Close?
Hi All,
I've been reading this forum for a few years, but this is my first post - so I'll start by saying a big Thank You to all those who have been so generous with their time and knowledge, in particular to:
- mCasual whose site is so useful.
- rbtwhiz
- Richard Haseltine
Now to my question:
I have a DzDialog with a "Close" DzPushbutton that calls a saveDataAndCleanUp() function and then calls the DzDialog.close(). That all works fine:
wDialog = new DzDialog;
wCloseButton = new DzPushbutton( wDialog );
wCloseButton.text = "Close";
connect( wCloseButton, "clicked()", doClose );
function doClose()
{
saveDataAndCleanUp();
wDialog.close();
};
function saveDataAndCleanUp()
{
// Save changed data, etc...
};
But my problem is that if the User closes the dialog by clicking the X button in the dialog's title bar, then my script gets no chance to execute the saveDataAndCleanUp() code.
The wDialog[] array of Members shows a "destroyed()" member, but it does not work for me (maybe because the dialog has closed but not actually been destroyed?):
connect( wDialog, "destroyed()", saveDataAndCleanUp );
In DAZStudio4 SDK/docs/qt/qdialog.html#finished there appears to be the potential for the desired signal, but this does not work either (but does not cause an error):
connect( wDialog, "finished()", saveDataAndCleanUp );
So:
Q1) Is there a way to ensure that saveDataAndCleanUp() gets called no matter how the dialog gets closed?
Q2) If not, then is there a way to disable or hide the X button in the dialog's title bar?
TIA.
Non-Modal scripting is possible, but needs care
There are a couple of other threads on this topic, but they say it cannot be done:
- http://www.daz3d.com/forums/discussion/65903/any-way-to-allow-scene-to-be-accessed-when-script-is-open/p1
- http://www.daz3d.com/forums/discussion/comment/657812/#Comment_657812
The trick is to launch the dialog Non-Modally, as described by Rob in the 2nd link above, and follow that with a local event loop.
There are a number of things that need to be taken care of that Modal scripting need not, especially ensuring that the local event loop gets terminated no matter how the dialog gets closed (the technique for this is per this thread). But it is probably no more open to mis-use than a Non-Modal plug-in is.
The attached file NonModalDialog.dsa is a working example, with lots of explanatory comments.
A couple of questions remain:
Q1) Is it a good idea to call sleep() each time thru the event loop? If so, what is the best value to use? (The example uses 50 ms).
Q2) Is it necessary to call gc() each time thru the event loop?
Q3) Is there anything else that needs to be done to ensure that a Non-Modal script behaves nicely?
Here's the example code in-line:
// NonModalDialog.dsa
// DAZ Script: Non-Modal Dialog tester and example.
// Revised 23-Apr-2016
// Created 15-Apr-2016
// Written by Praxis.
// Tested in DAZ Studio Version 4.8.0.59 Pro Edition (64-bit) under Windows7 Pro.
//****************************************************************************
//
// In the thread titled "how to make a modalless dialog?" of August 2014, rbtwhiz replied:
// | DzBasicDialog inherits DzDialog, which is a thin wrapper around QDialog.
// | Among other things, DzDialog exposes QDialog::exec(),
// | which ignores any modality setting when it calls QWidget::show().
// | DzDialog inherits DzWidget,
// | which provides a getWidget() method that will return the wrapped QWidget.
// | Because you can access properties, public slots and signals of a QObject in script...
// | you can actually set QDialog::modal to true and call QWidget::show(), and it will show... momentarily.
// | The problem is, show is non-blocking... so the script continues on to the next statement and ultimately finishes.
// | To avoid memory leaks, all DzWidget derived objects have "ScriptOwnership",
// | meaning they are owned by the script environment and are garbage collected when the script goes out of scope...
// | i.e. when the script finishes or crashes.
// | So, while you can actually create and show a modeless dialog in script,
// | the script will finish and garbage collect it before you have a chance to use it.
// | So, effectively... "no."
// |
// | Stylistically, a "modeless dialog" is implemented as a DzPane subclass in DAZ Studio.
// | And while portions of DzPane are exposed to script, you cannot construct one via script.
// | You must use the SDK for that.
//
// So we could provide a local Event Loop to process the App's events,
// while keeping the Dialog open until we really want it to close,
// and being careful to cater for the Non-Modal consequences.
// See items marked by: \\\NonModal
// Outstanding issues are marked by: ???Q
// Something like this...
// To minimize pollution of the script global namespace,
// use an anonymous function as this script's Main Routine:
// This limits the scope of this script's variables, etc.
// to just this script.
( function() {
//-------------------------------------------------------------
//---Script Globals---
//-------------------------------------------------------------
// See Note \\\NonModal_02:
// We need a flag to control our local Event Loop in executeTheScript(),
// and it must be accessible by the the code that Closes the Dialog:
var g_bTerminated = false;
//----------------------
//---Build the Dialog---
//----------------------
// Note \\\NonModal_04:
// --------------------
// If we create the Dialog with no Parent:
// var
// g_wDialog = new DzDialog;
// Then Qt will treat it as a "top-level" window,
// which is similar to being a separate Application,
// so User can close the DAZ Studio App and this Dialog will still survive,
// apparently running in its own execution thread in the Qt runtime system.
// (See Note \\\NonModal_05 for an attempt to prevent this).
// This is probably not the behaviour we want, so instead:
// Parent the Dialog in the App's MainWindow,
// so that the Dialog will be automatically Closed when the MainWindow closes:
// (A more accurate term for MainWindow here would be "Owner" rather than "Parent":
// MainWindow takes responsibility for destroying this Dialog.
// This Dialog's position is NOT constrained to be within MainWindow).
var
g_wDialog = new DzDialog( MainWindow );
g_wDialog.caption = "Non-Modal Dialog test";
g_wDialog.width = 400; // Make it a reasonable size, and wide enough to show g_wInfoText as 1 line
// Use a Layout so the controls auto-size nicely:
var
g_wDialogLayout = new DzVBoxLayout( g_wDialog );
g_wDialogLayout.autoAdd = true;
//---Property Controller---
// To be a realistic, useful test for a Non-Modal dialog, we need a bit of interaction with the Scene, so
// as an example add a Slider to control the selected Node's Y-Rotate property:
// (Not Scale, because e.g. Hip does not have that):
// Overall Property-Controller container:
var
g_wPropertyGroupBox = new DzVGroupBox( g_wDialog );
// Instructions to display when no Node is Selected:
var
g_wInfoText = new DzLabel( g_wPropertyGroupBox );
g_wInfoText.text = "Select a Node in the Scene... (Use the Node Selection Tool, or the Scene Pane)";
// Property-Value sub-container:
var
g_wValueGroupBox = new DzHGroupBox( g_wPropertyGroupBox );
// Slider to set the Value of the Property:
var
g_wValueSlider = new DzFloatSlider( g_wValueGroupBox );
g_wValueSlider.label = "Y-Rotate:"; // Sometimes labelled "Twist", etc. instead
g_wValueSlider.labelVisible = true; // Override the default
g_wValueSlider.textEditable = true; // Override the default: Let User edit the value directly
g_wValueSlider.toolTip = "Select a Node in the Scene, then use this slider to control the Y-Rotation of the Node";
g_wValueSlider.whatThis = g_wValueSlider.toolTip; // If we don't set any .whatsThis then the ? button captures the Mouse
connect( g_wValueSlider, "valueChanged(float)", g_wValueSlider_ProcessChange );
// Property Value Default Button: So User can easily reset to default value
var
g_wValueDefault = new DzPushButton( g_wValueGroupBox );
g_wValueDefault.text = "Default";
g_wValueDefault.toolTip = "Restore the property's default value";
g_wValueDefault.whatsThis = g_wValueDefault.toolTip; // If we don't set any .whatsThis then the ? button captures the Mouse
g_wValueDefault.autoDefault = false; // Override the default setting
g_wValueDefault.setFixedWidth( 50 );
connect( g_wValueDefault, "clicked()", restoreDefaultValue );
//---Close Button---
// Provide a Close button, so the User can choose when to close this Dialog:
var
g_wCloseButton = new DzPushButton( g_wDialog );
g_wCloseButton.text = "Close";
g_wCloseButton.toolTip = "Close the dialog";
g_wCloseButton.whatsThis = g_wCloseButton.toolTip; // If we don't set any .whatsThis then the ? button captures the Mouse
g_wCloseButton.setFixedHeight( 30 ); // Make it big and easy to click on
connect( g_wCloseButton, "clicked()", closeTheDialog );
//
// Note \\\NonModal_06:
// --------------------
// We don't want any Enter keypress to Close this Dialog,
// so we disable that default DzDialog behaviour
// by doing this for ALL DzPushButons we create in this Dialog:
g_wCloseButton.autoDefault = false; // Override the default setting
//---Connect the Dialog with the Scene---
// The Node in the Scene whose Property we are controlling:
var g_oNode = undefined; // : DzNode // Gets set by processSelectedNodeChange();
// We want to be notified whenever the Node Selection changes:
connect( Scene, "nodeSelectionListChanged()", processSelectedNodeChange );
// The numeric Property we are controlling:
var g_oFloatProperty = undefined; // : DzFloatProperty // Gets set by processSelectedNodeChange();
// Link the Node to the Dialog, and load the initial value:
processSelectedNodeChange();
//-------------------------------------------------------------
function closeTheDialog() // : void
{
// Event handler for g_wCloseButton.clicked()
// $$$ Testing: If the Dialog causes an exception, do both the Dialog and the Script (i.e. the Event Loop) get destroyed correctly?:
// throw( "Exception test." );
// Answer: Yes.
// See \\\NonModal_02:
// Signal our Event Loop in executeTheScript() that we want to Terminate this script:
terminateTheScript();
// Note \\\NonModal_03:
// --------------------
// We must Close the Dialog only AFTER calling terminateTheScript(),
// else we get this Script Error in our Event Loop in executeTheScript():
// | Error: cannot access member `g_bTerminated' of deleted QObject
//
// Close the Dialog:
// This is tidy, but not essential: The Script Environment would do this automatically
// once this script terminates, provided we built the Dialog per Note \\\NonModal_04 above:
g_wDialog.close();
}; // closeTheDialog()
//-------------------------------------------------------------
function g_wValueSlider_ProcessChange() // : void
{
// Event handler for g_wValueSlider.valueChanged()
// Load the Property's value from our control:
if( g_oNode ) {
if( g_oFloatProperty ) {
g_oFloatProperty.setValue( g_wValueSlider.value );
}
}
}; // g_wValueSlider_ProcessChange()
//-------------------------------------------------------------
function restoreDefaultValue() // : void
{
// Event handler for g_wValueDefault.clicked()
// Restore the Property's default value:
if( g_oNode ) {
if( g_oFloatProperty ) {
g_wValueSlider.value = g_oFloatProperty.getDefaultValue();
}
}
}; // restoreDefaultValue()
//-------------------------------------------------------------
function processSelectedNodeChange() // : void
{
// Event handler for Scene.SelectedNodeChanged()
// Disconnect any previously-current Node from the Dialog:
if( g_oNode ) {
disconnect( g_oNode, "transformChanged()", processNodePropertyValueChange );
}
// Save the updated reference:
g_oNode = Scene.getPrimarySelection(); // NB: Can = undefined
// Connect the current Node to the Dialog:
if( g_oNode ) {
// A Node is Selected:
g_wInfoText.hide();
g_wValueGroupBox.show();
// DzNode has no specific "rotationChanged()" signal, so we use the general signal:
connect( g_oNode, "transformChanged()", processNodePropertyValueChange );
// Load the Property's value and settings into our control:
g_oFloatProperty = g_oNode.getToolYRotControl();
if( g_oFloatProperty ) { // DAZ Script docs for DzNode say that this will always be true
g_wValueSlider.label = g_oNode.getLabel()+"."+g_oFloatProperty.getLabel();
g_wValueSlider.value = g_oFloatProperty.getValue();
g_wValueSlider.max = g_oFloatProperty.getMax();
g_wValueSlider.min = g_oFloatProperty.getMin();
g_wValueSlider.sensitivity = g_oFloatProperty.getSensitivity();
g_wValueSlider.displayAsPercent = g_oFloatProperty.getDisplayAsPercent();
}
} else {
// No Node is Selected:
g_wValueGroupBox.hide();
g_wInfoText.show();
}
}; // processSelectedNodeChange()
//-------------------------------------------------------------
function processNodePropertyValueChange() // : void
{
// Event handler for g_oNode.transformChanged()
// Load the Property's value into our control (if necessary):
if( g_oFloatProperty ) {
// Prevent recursion between this function
// processNodePropertyValueChange()
// and g_wValueSlider_ProcessChange():
// (This appears not to be necessary for most Properties, but play safe).
// NB: When comparing equality of fractional Numbers, treat equality to 6 decimals as "Equal":
// e.g.: eval( 0.1 + 0.2 == 0.3 ) returns false!
if( g_wValueSlider.value.toFixed(6) != g_oFloatProperty.getValue().toFixed(6) ) {
g_wValueSlider.value = g_oFloatProperty.getValue();
// Triggers a call to g_wValueSlider_ProcessChange()
}
}
}; // processNodePropertyValueChange()
//-------------------------------------------------------------
function terminateTheScript() // : void
{
// Signal the Event Loop in executeTheScript() to Terminate.
// See Note \\\NonModal_03:
// The Dialog must still be open here,
// else we get this Script Error in our Event Loop in executeTheScript():
// | Error: cannot access member `g_bTerminated' of deleted QObject
// See Note \\\NonModal_02:
// Signal our Event Loop in executeTheScript() that we want to Terminate this script:
g_bTerminated = true;
}; // terminateTheScript()
//-------------------------------------------------------------
function executeTheScript( p_Modal ) // : void
// p_Modal : Boolean // true==Modal, false==Non-Modal
{
// Launch the Dialog:
if( p_Modal ) {
//-----------
//---Modal---
//-----------
g_wDialog.caption = "Modal Dialog test";
g_wDialog.exec();
// Execution resumes here only after g_wDialog has Closed.
// // $$$ Testing: Can we still interact with the Scene, User Interface, etc. here?
// // i.e. The Dialog has Closed, but has not necessarily been Deleted yet.
// // Answer: Yes
// if( ( MessageBox.question( "Test after-Dialog operations?", "Modal Dialog", "Yes", "No", "" ) == 0 ) ) {
// // User pressed Yes
//
// // This works OK here:
// // i.e. The Dialog has been Closed, but not Deleted - just Hidden.
// g_wValueSlider.value = 90;
//
// MessageBox.information( "Press OK to continue...", "Modal Dialog post-processing Tested", "OK" );
//
// // $$$ Testing: Can we still re-launch it?:
// g_wDialog.caption = "Modal Dialog test #2";
// g_wDialog.exec();
// // Answer: Yes
// // If we wanted, we could probably relaunch it Non-Modally too.
//
// }
} else {
//---------------
//---Non-Modal---
//---------------
// Launch the Dialog and the local Event Loop:
//---Launch the Dialog Non-Modally---
g_wDialog.caption = "Non-Modal Dialog test";
// Note \\\NonModal_01:
// -------------------
// See info re .modal in "DAZStudio4 SDK/docs/qt/qtdialog.html"
// Instead of g_wDialog.exec(),
// which does not return until something Closes the Dialog,
// do this to launch Non-Modally:
g_wDialog.modal = false;
g_wDialog.show();
// Execution continues here immediately...
//---Local Event Loop---
// See Note \\\NonModal_05:
// If the Dialog becomes Hidden, we ASSUME is has Closed, and so we Auto-Terminate this loop.
// But only after it has first been Shown - so we need a flag to track that:
// DzDialog has no OnShow Event, so we must make our own equivalent:
var DialogShown = false;
// Extra safety precaution:
// Try to ensure this event loop gets terminated at the latest when the App Terminates:
connect( MainWindow, "aboutToClose()", terminateTheScript );
// Note \\\NonModal_02:
// --------------------
// We need a local loop that continuously calls processEvents():
// Without this, the Dialog flashes on screen, then disappears and the script terminates:
// With this, the Dialog remains on-screen and usable until its Close button is clicked,
// and all other Interface facilities are available as well - Camera controls, Parameters, etc.
g_bTerminated = false;
while( !g_bTerminated ) {
// See Note \\\NonModal_02:
// This is essential:
// Let the App process its Events, including our own g_wCloseButton.clicked() event,
// until our g_wCloseButton.clicked() event sets g_bTerminated = true:
// This allows the User to use all the standard interface controls that are not part of the Dialog,
// e.g. Camera controls, DrawStyle, Parameters, etc.
processEvents();
// NB: At this point, g_bTerminated may = true, so we must test it before doing other stuff here:
if( !g_bTerminated ) {
// $$$ Testing: If we auto-Terminate here, does g_wDialog get automatically Closed?:
// g_bTerminated = true;
// Answer: Yes
//---Detect whether the Dialog has been Closed---
// Note \\\NonModal_05:
// --------------------
// If the User Closes the Dialog via the g_wCloseButton button we provided,
// then it calls terminateTheScript() and all is OK: This event loop will terminate.
// But the Dialog can be Closed in a number of ways:
// 1) g_wDialog.close() was executed.
// 2) The User clicked the X button in the Dialog's Title bar.
// 3) The User right-clicked the Dialog's Title bar, and chose Close from the popup menu.
// 4) The User pressed Alt+F4, which is the shortcut for 2) above.
// 5) An unhandled exception occured in some part of the Dialog's code.
// We must cater for ALL ways, otherwise this event loop will continue to run,
// with no way for the User to terminate it other than terminating the entire App.
// Ideally, DzDialog would provide a "finished()" signal that we could connect to
// terminateTheScript():
// See DAZStudio4 SDK/docs/qt/qdialog.html
// | void QDialog::finished( int result ) [signal ]
// | This is emitted when the dialog's result code has been set.
// But as of v4.8 this is not available, so we must test something else...
//
// When the Dialog is Closed, it is immediately Hidden too - which is something which we CAN test:
// But we need to test DialogShown as well, else the Dialog would never appear,
// because the 1st pass thru this loop would set g_bTerminated = true:
if( g_wDialog.getWidget().visible ) {
// Signal that we can now Auto-Terminate the Dialog if it becomes hidden:
DialogShown = true;
} else {
// The Dialog is not visible
if( DialogShown ) {
// The Dialog was visible, and now is not.
// Something has Hidden the Dialog without calling terminateTheScript().
// The Dialog has been Hidden, so we ASSUME it has Closed:
// If we don't detect this condition here and Auto-Terminate the script, then
// the Script appears to have hung, and the only way to correct it is
// to terminate the entire App.
// $$$
// print( "Dialog has been hidden: Auto-Terminated within Event Loop." );
// Auto-Terminate:
g_bTerminated = true;
} // The Dialog has been Hidden, so we ASSUME Closed
} // The Dialog is not visible
} // Not yet Terminated
if( !g_bTerminated ) {
// ???Q_01: This seems to be a good thing to do here?:
// Prevent this loop from using too many CPU cycles: Give other threads more time to execute.
// Note: This just slows down this local loop - not the App's normal processing.
sleep( 50 ); // Pause this script for a bit, without blocking the App's event loop
// ???Q_02: Is this necessary here?:
// See DAZStudio4 SDK/docs/qt/qtcoreapplication.html#processEvents
// | In event you are running a local loop which calls processEvents() continuously,
// | without an event loop, the DefferredDelete events will not be processed.
// | This can affect the behaviour of widgets, e.g. QToolTip,
// | that rely on DeferredDelete events to function properly.
// | An alternative would be to call sendPostedEvents() from within that local loop.
//
// These both cause errors here:
// sendPostedEvents();
// App.sendPostedEvents();
//
// Is this equivalent? Or does it just slow the App down?
gc(); // Tell the global Garbage Collector to do its thing
} // Not yet Terminated
} // Until something sets g_bTerminated = true
} // Non-Modal
}; // executeTheScript()
//-------------------------------------------------------------
// Launch the Dialog, etc.:
// We could e.g. Launch Modally if the Ctrl key is down, etc.:
executeTheScript( false ); // true==Modal, false==Non-Modal
// Finalize the anonymous function, and immediately invoke it as this script's Main Routine:
} ) ();
DzConnect is unavailable in DAZ Script
Every time I try to subscribe to signal of a button I get "Can't find variable DzConnect" error message. Typeof DzConnect also gives me undefined. So it's basically isn't there and without it there's no way to use buttons.
I use Studio v.4.9.1.30
disconnect widgets? " failed to disconnect"
Hello,
I'm trying to disconnect widgets but I don't manage to do so. I probably don't use the right commands. I have tested a few of them, but there must be a mistake. Does anybody see what I'm doing wrong here?
Here is an example of what happens (I made it short, initial version is much longer). The function I connect is here a simple message saying you're still connected. I have 2 loops, the first one supposed to connect, the second to disconnect. In my real script the second loop will be activated by a signal. But I don't manage to disconnect :(
edit : in details:
wMywidget[k].textChanged.disconnect( wMywidget[k], functionForThisWidget ) leads to an error, so you can remove this line if you test it.
The other disconnect(....) don't seemm to diconnect.
var n = 3;
wDial = new DzBasicDialog();
wBox = new DzVGroupBox(wDial);
var wMywidget = new Array;
for (k=0; k<n; k++)
{
wMywidget[k] = new Array;
wMywidget[k] = new DzLineEdit(wBox);
wMywidget[k].text = "my text"+k;
connect(wMywidget[k], "textChanged(const QString&)", functionForThisWidget);
}
for (k=0; k<n; k++)
{
disconnect(wMywidget[k], "textChanged(const QString&)", functionForThisWidget);
disconnect(wMywidget[k], "textChanged(const QString&)");
disconnect(wMywidget[k], "textChanged(const QString&)", 0, 0);
disconnect(wMywidget[k], "textChanged()", functionForThisWidget);
disconnect(wMywidget[k], "textChanged()");
disconnect(wMywidget[k]);
wMywidget[k].textChanged.disconnect( wMywidget[k], functionForThisWidget ) // you can remove this lines it leads to an error
}
function functionForThisWidget()
{ print("Still connected") }
wDial.addWidget (wBox);
wDial.exec()
Compiled scripts and older versions of DS...
I just learned from QA that a compiled script only works in DS at the same or higher version than the version in which it was compliled. Is there a reason for that, and is there a way to "fix that"? Having 4.9.1.30 (last release version) and the compiled script won't work in 4.8. I want to compile it, at least be script backend, it it a rather complicated script that I don't want to be "flying around" as I will probably use that backend in more products.
Hints or tips anyone?
Add pose .duf file to smart content?
Is it possible, and if so, any example script, to add a pose preset to smart content with Daz Script?
How to find Preset (.duf) in Smart Content
Is there a way to find out:
1) If a preset file (.duf) is in smart content; and if so:
........2) Information from that asset like: Type and Category?
I tried searchForAssets in DzAssetMgr, but it errors if I use the full path. If I just use the preset file name that really will not help if, for example, a pose preset that is named 01.duf.
And as I'm playing with searchForAssets, it is only working in the Script IDE, in debug, and if I step to it. All other ways are returning empty :(
A script to Orbit Camera around a point
This topic seems to come up occasionally, but I couldn't find an existing "Orbit Camera" script, so I've written one (CameraOrbit.dsa) and attached it to this post. It shows one way to Orbit Camera around a point, via Slider controls.
It lets you control the Longitude, Latitude and Radius of the Orbit.
By default it controls the built-in Perspective Camera of the Viewport, and Orbits around the point [ 0, 100, 0 ], but:
* If your Scene contains a visible Node labelled "Orbit-Point" then that will be used as the point to Orbit instead.
* If your Scene contains a visible Camera labelled "Orbit-Camera" then that will be used as the controlled Camera instead.
You can enable/disable this behaviour by simply turning off the Visibility of what you don't want to test.
The guts of it is the maths to convert between Cartesian and Spherical coordinates, as per Wikipedia: Spherical coordinates
Hope you find it useful.
Typed array in Daz script
I have a javascript library that reads and writes C++ style data in binary format from/to a file. To do that, I use typed arrays (float32array,arraybuffer...).
I need to port this library to Daz/QtScript. QTScript is supposedly compatible with ECMA-262 which defines typed array, but I can't manage to make it work.
Does anybody have tried that ?
"ç" and the size of the script (never use a "ç")
Hello,
I have an issue with one of my script. I'm using "AppSettings.setStringValue( "path" , FileInf.path() );" in one of my scripts in order to remember some useful path for the user.
This command is in a function launched by widgets.
The issue I have now is that as soon as save my file, the size of the dsa gets bigger and bigger. Now after a few save is is too big to be opened by anything (131 Mo). Yet the number of lines has not changed (around 4500). I don't understand what is happening?
Does anybody have an idea what is happening?
Edit : finally it did not comme from AppSettings, but from a "ç" which was in one of my comments and lead to a huge mess. I'll remember not to use special characters now!
A script to control a selected Property, with large font size, and Preview buttons
The font size in the Parameters Pane is too small for comfortable use for me, and the controls for fine-tuning a value are a bit indirect, so I've written this to help me in these particular areas.
I find it very useful when Shaping or Posing a figure, to fine-tune the settings, e.g. to easily see the subtle difference between the Genesis 2 Female "Fitness" morph applied at 0.5 vs 0.6
The attached PropertyController.dsa file (160 KB) is a free, un-encrypted script that provides an alternative to the standard "Parameter Sliders":
- Larger, more-readable Value displays.
- Single-Click restore Initial value.
- Single-Click toggle between Initial and Current Values.
- Single-Click restore Default value.
- Single-Click toggle between Default and Current Values.
- Single-Click toggle between 2 User-specified Values.
- Single-Click specification of Nudge Size.
Instead of trying to provide large font and preview buttons for each Property, this provides them for just the currently-selected Property.
It also contains basic Viewport and Animation controls, some reporting utilities, and basic Help text.
Although its free, and hopefully useful to non-Developers, I've posted it in this Script Developer forum instead of in the Freebies forum because:
a) I hope it won't be needed for long: I hope that DAZ will provide an equivalent Tab in the Parameters/Posing/Shaping/Surfaces Panes, so that I/we can get these benefits without having to reproduce so many standard controls (Viewport, Animation, etc.) in a "modal" dialog.
b) I'm much more interested in feedback from DAZ and Developers about what script techniques would be better for doing this sort of thing than End-User feedback (although I would still appreciate that).
In more detail:
- The script works on floating-point numeric properties only - but that is most of them, and other types could be added quite easily.
- I've tested it with Studio v4.8.0.59 and Windows 7 Pro.
- It still has some rough edges (e.g. no "Undo" facility, could be purer "OOP", more-standardized naming conventions, etc.), but I don't intend to polish it any further - I hope DAZ will soon build in the equivalent.
Here's a partial screenshot:
1) The dialog.
2) Node Selector: Lets you select any Node in the Scene, and displays its label in large font.
3) Property Selector: Lets you select any (floating-point) numeric Property of that Node, and displays its label in large font.
4) Value display, in large font.
5) Slider to control the Property's Value.
6) Single-Click Preview buttons (as described at the start of this post).
7) Single-Click specification of Nudge Size for the Slider's auto-repeating +/- Nudge buttons.
8) Selector for the font size for the Node Name, Property Name, and Property Value displays.
9) A convenient button to launch this script via a "Custom Action"
(Created via Menu: Window > Workspace > Customise...)
The script demonstrates one way to do a variety of things that could be needed in "modal" scripts for many other purposes, and its the improvement of these techniques that I'm most interested in:
In a modal dialog, provide controls that are sort-of equivalent to the standard controls that are not available there:
Node Selector
Property Selector
Camera/View Selector (Perspective, Front, Custom Camera, etc.)
Perspective Camera:
Orbit left-right
Orbit up-down
Dolly in-out
Zoom in-out (adjust Focal Length)
Orthogonal Camera:
Pan left-right
Pan up-down
Dolly in-out
Frame selected Node
Aim at selected Node
Reset Camera
Draw Style Selector (Wire Shaded, Texture Shaded, etc.)
Show/Hide Bones
Miscellaneous techniques:
Display data in a large font size.
Save/Load preference settings that persist between sessions.
Launch an independant viewer for a text file (e.g. a report of which Nodes have non-Zero Transforms).
Object inheritance: How to call inherited functions of the .superclass, etc.
(Not actually needed in this script, but my next project involves a hierarchy with about 5 levels).
I hope you'll find it useful - feel free to modify it to suit yourself.
-P
How best to structure a large script project?
Hi,
To make development of my large project manageable, I've split it into a number of separate files, which I "include()" in my main .dsa file. (I'm not concerned about any multi-file distribution issues at present).
The documentation for Global.include() says:
"This function should only be called within the global scope of the script; it should not be called within a nested scope and it should not be called inline."
So all the include() commands are issued in the outermost scope of the script, before the main function of the script, within which I assume would be "nested scope".
It all appears to work OK so far, but I'm concerned about how much "pollution" of the Global namespace this causes, and how much is tolerable:
If an object "class" is declared in the global scope of the script (as it would be when include()ed from a separate file), does that count as only 1 global symbol, or do each of its member functions count as global symbols? (I assume the member variables don't?).
To illustrate, is the following an OK way to do things?:
A separate file that will be included:
// MyTypeDefA.dsa
// Constructor:
MyTypeDefA.superclass = Object;
function MyTypeDefA()
{
// Member variables:
this.m_nVar001 = 1;
this.m_nVar002 = 2;
...etc.
this.m_nVar999 = 999;
};
// Member functions:
MyTypeDefA.prototype.function001 = function() { ...etc. };
MyTypeDefA.prototype.function002 = function() { ...etc. };
...etc.
MyTypeDefA.prototype.function999 = function() { ...etc. };
Another separate file that will be included:
// MyTypeDefB.dsa
// Constructor:
MyTypeDefB.superclass = MyTypeDefA;
function MyTypeDefB()
{
// Member variables:
this.m_sVar001 = " 1";
this.m_sVar002 = " 2";
...etc.
this.m_sVar999 = "999";
};
// Member functions:
MyTypeDefB.prototype.process001 = function() { ...etc. };
MyTypeDefB.prototype.process002 = function() { ...etc. };
...etc.
MyTypeDefB.prototype.process999 = function() { ...etc. };
The main script file:
include( "MyTypeDefA.dsa" );
include( "MyTypeDefB.dsa" );
// Use an anonymous function as this script's Main Routine:
( function() {
// Create some instances:
var g_oInstanceA001 = new MyTypeDefA();
var g_oInstanceA002 = new MyTypeDefA();
...etc.
var g_oInstanceA999 = new MyTypeDefA();
var g_oInstanceB001 = new MyTypeDefB();
var g_oInstanceB002 = new MyTypeDefB();
...etc.
var g_oInstanceB999 = new MyTypeDefB();
...etc.: do stuff...
// Exit.
// Finalize the anonymous function, and immediately invoke it as this script's Main Routine:
} ) ();
... or is there a better way in DAZ Script?
Thanks for any feedback.
Adding an Icon to a script
It's surely a silly question, but how can I associate (and distribute) an icon for a script ? I've googled it to no avail.
DzLine3 object
OK this is driving me a bit nuts at the moment (and probably because I'm missing something very fundamental). I can't use any methods on a DzLine3 object, I just get the "undefined is not a function errors...
(function(){
var oLine = new DzLine3();
oLine.origin = new DzVec3( 0,0,0 );
oLine.end = new DzVec3( 1,1,1 );
var nLength = oLine.length();
print(nLength);
})();
always results in the follwoing output
Executing Script...
Script Error: Line 7
TypeError: Result of expression 'oLine.length' [undefined] is not a function.
Stack Trace: ()@:7
Error executing script on line: 7
Script executed in 0 secs 2 msecs.
What am I missing?
Differences between Studio 4.6 and 4.9
I have a script that fails to start in Studio 4.6 although it's working very well in 4.8 and 4.9.
Has there been any significant change in the scripting part between those version ?