Convert to SubD script
Soto
Posts: 1,440
I`d like to include a script to convert the selected item to SubD.
Actually, the idea is to create presets so the user can toggle between 0 and 1 subdivisions for the selected item.
I don`t know where to look at, so I would appreciate a help with this, please.
Comments
The first thing that comes to my mind is trigger the DzSubDAction, then through properties change the subdivision values.
Here is simple code to trigger an action.
This should give you an idea how you can set the properties you're looking for, Hellboy:
var nodes = Scene.getSelectedNodeList();
var n = nodes.length;
for( var i = 0; i < n; i++ )
{
var oObject = nodes[i].getObject();
if( oObject )
{
var oShape = oObject.getCurrentShape();
if( oShape )
{
oProp = oShape.findPropertyByLabel("SubDivision Level");
if ( oProp )
{
oProp.setValue(0);
}
}
}
}
Hope this helps.
- Greg
Oh yes! It does help indeed! This is really helpful.
Thanks to you both! :D
Hello!!!
I was looking for this thing exactly... a way to have a script for ON OFF the SubD... but I am not too good as for writing this code or I am doing something wrong because it doesn´t work on me...
How can I make these scripts??? Please help!
Fabi
I modified algovincian's code to check if SubD has been applied, then sets the desired sub level, you can turn off SubD by setting the value to 0, or turn it on by setting a desired level from 1 to 5.
Just copy this snippet to a script file(.DSA)
thank you!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Thank you for this script.
I want to start with scripting and picked this example to understand what this does.
However I tried it to also set the Resolution Level to Base with no succes. There are a few things I want to know - but my fist question is:
You asking for "oShape.findProperty("lodlevel")) && oProp.getNumItems() && actionMgr.findAction()" but Property "lodlevel" Resolution Level keeps in High Resolution state after this script.
Now I want to set the Property "lodlevel" Resolution Level to Base - but I cant set lodlevel=Resolution Level to My_MeshResLevel = 0 why? [Edit]: [Solved]
See my Example:
...sorry double post
Excelente documentation.
You are missing a closing paren.
Oh cool now its working typical beginner mistake - forgive me its my fist one ever.
Hi,
I want to show you my new completly reWritten version of this script Example. Therfore I have changed the FileName to this meaningful creation: ApplyOrZero_SubD_SubDivLevel_MeshResLevel.dsa
I hope I could clean up this mess. I've also added a new idea I had as I read in this Example Script:
Until now I have no Starter script to call this one to test the passed Arguments.
But for now the Script IDE console tells me:
Executing Script...
general\dzscript.cpp(658): Unhandled error while executing script.
QScriptEngine::popContext() doesn't match with pushContext()
Result:
Script executed in 0 secs 655 msecs.
Please help me with the Sring operations String.join () / String = text ("...") ...and damn so much paren (((((...).).))..
And here is my complete Script Example click FileName to download: ApplyOrZero_SubD_SubDivLevel_MeshResLevel.dsa 8K
//pass arguments to Apply - Or - Zero with no Arguments passed - at least I hope to get it to work this way - please comment if you have other suggestions.
[Edit] 1: I've updated the code now the Script IDE tells me a not that fatal error anymore:
Executing Script...
Script Error: Line 40
SyntaxError: Parse error
Stack Trace: ()@:40
Error executing script on line: 40 //its eigther the fist or the last line that shows me an error cant get anonymous function to run?
Script executed in 0 secs 3 msecs.
Still I cant get it to run - never could test anything in it - even I thought of a extended error detection - It should be foolproof to some extend now - with very detailed Infos in the resulting MessageBox.
And here is my complete Updated to v2 Script Example click FileName to download: ApplyOrZero_SubD_SubDivLevel_MeshResLevel_v2.dsa 12K
[Edit] 2: I've updated the code now the Script IDE tells me NO! error anymore but my MessageBox get showen at the end and the values get set:
Still no succes with passing Arguments I just dont know how the syntax should look for this to work. If I try I have eighter syntax error in the first or the last line.
My other problem now is that I think I missused the String.Join () funcition no sMessage String is showen in the resulting MessageBox. I think I have to fill an ordenary array and then give it to sMessage in the last step. But still no luck.
Please help I have no idea how to work with these strings? And "\n" is the "new line" symbol I thought or is it the strings last terminator symbol?
eg. sMessage = String.join ( "This" + "This too" + "\n");
eg. aMessage[aMessage.length + 1] = text (" ");
eg. aMessage[nSucces + nError] = aMessage.concat (" ");
eg. aMessage[nSucces + nError] = aMessage.join (" ");
Maybe its better to just use print (""); to the console. But I would like to see what this scipt had done with my scene selection in the messagebox.
And here is my complete Updated to v3 Script Example click FileName to download: ApplyOrZero_SubD_SubDivLevel_MeshResLevel_v3.dsa 14K
And here is my complete Updated to v4 Script Example click FileName to download: ApplyOrZero_SubD_SubDivLevel_MeshResLevel_v4.dsa 15K
[Edit] 3: I've updated the script finaly it does what it should. I've added some things and improved the code.
Still no succes with passing Arguments but finaly a working version now.
Improvments:
Still much to improve. Im not happy with the formating of the messagebox output while I was writing this script without getting anything into the messagebox I was handling the text output more like a console output. I was experimenting with oObject.getLabel(); and oObject.getName(); but still it will show the label not the name of the item.
To-Do:
See this example screenshot to get what I mean. I had Genesis 2 Female, a sphere, a cube, a Null and a Camera selected:
Next I will have a closer look at the DzWidget Documentation. I would like to have something like this Action Accelerators for my final messagebox.
Can I please borrow some of the DzWidget related Action Accelerators source code to have a propper listbox for the final message?
I mean its a common userinterface element and if you look whats left from the other SubScript example code in my current script version - its basically the "function text( sText )" and the for-loop "for( var i = 0, nArgs = aArgs.length; i < nArgs; i += 1 )".
I've skipped over to version 7 for this release now - maybe I should have thought of a better version numbering like v0.7beta for this.
And here is my complete Updated to v7 Script Example click FileName to download: ApplyOrZero_SubD_SubDivLevel_MeshResLevel_v7.dsa 20K
423 lines of code this time it dosnt fit into the Code Snippet container box anymore. It tells me Body is 2139 characters too long.
Therfor no script preview anymore. Maybe better you dont have to scroll that long to the bottom of this thread by now. I wonder why you cant collapse this forums Code Snippet container by default?
You can't use the sample scripts and make the result no rights reserved, the Open Source with Attribution license does plae restrictions (specifically that attribution must be given) on the script and anything derived from it.
As for the error, we've seen that a couple of times - check that you are not redeclaring a variable inside a loop, especially if recursing.
The for loop is not necessary, why dont just wrap the code like:
@jag11: Thanks, for the example code - this stuff is very useful to understand and can be quiet handy for bigger projects. Its like working with the include in Javascript or the C++ headers.h library.
So instead of being lazy and run a anonymouse function you can define and descripe a whole set of functions.sub-functions within a single script file. If you have written a set of functions doing basic stuff you can work with them from outside in another script if you add the line: include( "MyCustomScriptsAndFunctions.dsa" ); on top you can add them to your next script project and write more advanced functions with them.
Its this method of passing arguments that I'd like to understand - thats why I picked this SubScript Example.
But I think I misunderstood the Callee_Script.dsa example. I thought the for-loop is necessary to determin the datatype of the passed arguments that are loosing their datatype by passed over in this string array that needs to be somehow detected and restored within this for-loop. But what I see now is that just for this special example the for-loop does convert all datatypes of the passed arguments to this sMessage string to see them in the Messagebox. And also "if ( nArgs > 0 )" dosnt makes sens in this for-loop I must have been half sleeping.
Back to your script example: lets call it ConvertToSubD.dsa to use it in another script I just have to write this right?
and this will give me two variables subDLevel, lodLevel ofType: float ???
my_Array[i] = this.changeMeshResolution(parseFloat(args[0]), parseFloat(args[1]));
@Richard Haseltine
Sorry this was a joke - I'm not shure about this rights reversed thing but I wanted to include some header - copied the original DAZ one and added some lines to show the sources and inform about the modifications like from what I know the licence prescribes.
Thanks for this good advice not to declare variables in loops now I see why - again a typical beginner mistake - dont show errors in the inspector console but can write a new variable to the memory with every loop I think.
LOL its done even within the original code snippet:
Variables can be local, but I have had the pop context issue myself and sceen it from others and it seems to be related to having things out-of-scope in soem way, which redeclaring variables on each pass of a loop does seem prone to.
As for licensing, it's important to remember that Rob is writing these sample script in his own time to help us get the most from DS, so beyond the simple legallity issue it's important to espect his wishes on usage. https://wiki.creativecommons.org/wiki/License_Versions#No_sublicensing explains that the license terms are set by the original author and can't be modifed by a subsequent user.
Now I get what your are trying to do. Pick the stone according to the size of the toad. The previous skeleton code was designed to be called from another script. The library code skeleton looks something like this:
To call functions inside your library, you need something just like this:
MeshTools is defined like a static class and changeMeshResolution is a static method.
Apparently scope is never less than the function, so declaring the variables in the loop should be significant here. If you want to have a variable with limited scope you can use the same anonymous fnction technique used in most of the samples scripts within a function, though that will have an impact on performance.
That's more of an aside than directly relevant, other than indicating that I was wrong to regard the location of your variable declarations as a plausible cause for the pop errors.
See my [Edit] 2: I've updated the code now the Script IDE tells me NO! error anymore but my MessageBox get showen at the end and the values get set:
ApplyOrZero_SubD_SubDivLevel_MeshResLevel_v4.dsa
I'm currently working on v5 that uses the undo Stack it works partialy but not for lodLevel for now.
@Richard
Dont worry about the QScriptEngine Error I did something completly wrong there - but it dosn't matter that much because with the new concept ideas from jag11 how to encapsulate the code I see that I have to do things different - much work to do and learn how to write working code now.
I dont want to run into legallity issues here and I have great respect for robs work and wishes on usage. I only borrowed the source code of the Sub Script Example to demonstrate my new concept.
I have included the licence URL and edited the legal notes with my update.
@jag11
You get it I aim for a much bigger plan than just get this "Convert to SubD Script" running.
I would like to include some other code snippets that I saw in this forum and create a library for me and others to use and maintain.
But it needs to be easy to use and with error detection and it should be foolproof to some extend.
With messageboxes for the average user that can be switched to silent mode with bDebug or similar and print messages to the console for the script coders.
Static Class MeshTools.. I dont know - how about SubD or is it allready in use?
eg. SubD.ChangeViewSubDLevel (4);
eg. SubD.ApplySubD();
Name it whatever suits you best.
As for error detection I prefer the old try/catch model, but if you validate enough, errors practically dissapear.
I've updated my fourth post.
[Edit] 3: I've updated the script finaly it does what it should. I've added some things and improved the code.
After a few more tests now with the current version v8 I see that it isn't that easy to tell if the SubD Modifierer is allready applied or not.
Now I do the following: remember what the lodlevel was switched to before then try to switch it once off then on and see if this was possible - then turn it back to the remembered state it was before. Dose this make sense and whats the resulting state of lodlevel after this check? I'm a bit confused now this should be the best option for a workaround the other I can think of is checking if the View SubD level Property is hidden or not.
The other thing is I'm surprised that its seems that I was able to undo the Convert to SubD action - maybe possible because the object wasn't saved as Content like a Figure/Prop Asset and its all just the current state in memory.
See my current SubD check routine:
Some checklist:
if ( ( oProp = oShape.findProperty("lodlevel") ) == true ){}; tells you that there is a Resolution Level Property this is true for all objects with geometry
vCheckSubD = oProp.getValue("lodlevel"); the value of vCheckSubD tells you if it is switched to Base = 0 or HighRes = 1
if ( ( oProp.setValue( 1 ) ) == false ){}; should tell you that it is not possible to set the value to HighRes = 1 because the object isn't yet Converted to SubD
To find out if the SubD was already applied the code segment oProp.getNumItems() returns 1 only when it is not SubD'ed, after it is SubD'ed it must return 2 elements "Base" and "High Resolution".
Cheers
Ah thanks,
and I thought of why to ask for Items because I only got the focus on one node - these Items != Scene Items.
Slowly but continiously I get what these lines actually means.
So far so good
With my current working version v8.2 I want to make things diffrent like before. Its time to break up all these long for loops and if/else condition chains all written into one continious anonymous function.
You may had a look into my script v7 - I use the new functions InfoMsg ErrorMsg there - they do allot for me (write a single message line into the their Message array and count succes/error ) and by doing this, break up the task to manage into smaler tasks that are clearly layout.
Currently I'm reaching the mark of 449 lines of script code - I'm loosing the overview by scrolling through especialy with the indents by tab stops.
I know, these are all just smale steps towards a final script program that should be well organized and follows the guidlines of a object orientated programming desing.
I'm thankful for the suggestions from jag11 how wrap the code into seperate functions.
My script function(s) isnt/arent yet able to be called from another script - but before that can happen I want to make shure the structure is well organized.
External Script Editor Usage
I dont use the Script IDE to write this - as long as the Script IDE pane dosnt jump into the line in wich the syntax error occured its not much of use - but to provide basic functionalities with the sytax error inspector.
My tool of choice is https://en.wikipedia.org/wiki/UltraEdit current version 24 provides a solid scripting IDE interface.
The Extensible code highlighting is customizable with Java or C++ settings its OK to work - maybe there could be a code highlighting for DazStudio Qt syntax?
If you want to get real crazy you can use Find/Repace in Files to find and fix erros like wrong paths written in saved uncomressed *.duf files or use also their other tool -have a look at Ultra Compare.
With all this - again some incompatibility between diffrent programs had to be fixed - so I had to reconfigure my script editor to use 4 instead of 3 spaces for a tab stop in DazStudio the tab stop is 4 spaces long and in the script snippet box the tabstop is huge 8 spaces long. On top of that - if you copy/paste code into the snippet box all //Commentlines jump way to far to the right - then you can delete tabs but not add them there.
Sorry but this can mess up things quiet easy - especialy if you have to work with DazStudio in conjunction with the Script editor. And also copy paste code to the script snippet box.
What I do is I load the script file *.dsa into the Script IDE pane and if I had made changes to the file with the extrenal script editor by Ctrl+S and want to test this script version I go to the IDE pane: File>Reload Script action or use my shortcut Ctrl+Shift+R to refresh the currently loaded file by DazStudio. This is one workaround I have found - one thing that I think is counter productive is that you cant drag&drop the script files *.dsa into the IDE pane from the Content Library. Maybe its possible to somehow trigger the action Reload Script if you switch tasks - like to hook Reload Script to some DzApp event?
Questions about global / local declarations of variables acording to passed arguments in functions
Its about what I did wrong in the first place - not knowing about the local/global scope of defining variables. With the following Example I want to show what I'm not shure of if there can occure conflicts with the names of global/local declarations. In this example nArgs, aArgs, aMessage are named the same in global and inside the local focus/scope of the Check_Args function - does DazStudio work with them like with local copys/clones of the global counterparts?
As an end-user, just wanted to say Thank you! to all in this thread for this public resource.
DL'd Syrus Dante's v7 dsa, made 6 copies and modified each to a different setting. Added all 6 one clicks to a Visual Menu (Bitwelder's product) and life got a bit quicker again.