How to grab the texture map of a surface

V3DigitimesV3Digitimes Posts: 3,123
edited December 1969 in Daz Script Developer Discussion

Hello,
I need to apply one map generally assigned to one variable (for instance diffuse color) to another variable (for instance translucency color), by a script.
I'm a beginner so please be indulgent :)

For now, here is the end what I have written, helped by a script Rob provided to me a while ago (the script works to grab a value on variable having no map, but when there is a map... ouch...) :

 DsActions.prototype.setMaterialProperties = function( oMaterial, oShape ){ this.m_oElement = oMaterial; var sID = this.m_oElement.name; if( oShape != undefined ){  sID += "_" + oShape.getLabel(); } // DAZ Studio version 4.6.3.49 filetype DAZ Script // Thanks ONCE AGAIN to Rob for providing some parts of the following code. // <a href="http://www.daz3d.com/forums/discussion/42842/">http://www.daz3d.com/forums/discussion/42842/</a>;// Define the list of names you care aboutvar aSurfaceNames = [ "Torso", "Hips" ];// Define the name you want to checksFind = sID// Check if the name is in the listvar nIndex = aSurfaceNames.indexOf( sFind );if (nIndex > -1) {  var aPROPERTIES = oMaterial.getPropertyList(sID); var oProperty, oOwner, oValue; for( var i = 0; i < aPROPERTIES.length; i++ ){  oProperty = aPROPERTIES[ i ]; // on remply l'array    oOwner = oProperty.getOwner();   oValue = oProperty.getValue(); // on attrape la valeur  oNames = oProperty.getName (); // de cette variable  print (oNames)  print (oValue)      if (oNames ==  "Diffuse Color") {..... // tex = oNames.getMapValue();       //      filename = tex.getFilename();

And I stopped there, because I realised I don't know how to have the map value alone. I tried ".getMapValue" but I have a message error
Result of expression 'oValue.getMapValue' [undefined] is not a function...
Any idea what I could use?
Thanks in advance for any help of any sort!

«1

Comments

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    oValue is a number, you want to use getMapValue() on oProperty itself, first using isMapped() to make sure that there's a map to get (and not a flat colour).

  • V3DigitimesV3Digitimes Posts: 3,123
    edited December 1969

    oValue is a number, you want to use getMapValue() on oProperty itself, first using isMapped() to make sure that there's a map to get (and not a flat colour).

    And it works!!!
    Thank you so much Richard! if I had a "blow kiss" smiley, this should be place exactly here in this post!

    I've finally managed to write the full script catching a map to place it somewhere else! I'm not sure it is really "clean" because I did not understood everything I made (100% trial/error method), but it works.

    Now I just have to find out how to load and apply a shader definition asset, or a shader, in the same dsa file. My little finger tells me my troubles are not over ;)

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    Try saving a Shader preset using the deprecated script format and pick that apart.

  • V3DigitimesV3Digitimes Posts: 3,123
    edited December 1969

    Yes, Richard, I remember already had other things working this way in other project with my amazing skins. The drawback is that the brick network is embedded in the dsa file. This is why I wanted to avoid this method, first because while still in development stage, the brick network is often changed, and each time I have to re-modify the dsa, and also because a shader definition asset protects "just a bit" more the author work.

    I have second possibility which is to create a dsa calling my main duf, then the "map mover" dsa I just finished. I remember I read somewhere a dsa could call a duf (or the contrary?)

    I have a last possibility which will be to keep 2 files "apply me first" (the material) "apply me second" (the maps in the right place). This is not an elegant solution (but sometime pragmatism wins over elegance).

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    Yes, you could grab the settings, apply the .duf for the base shader, and then restore settings - the only risk would be idiots like me who can never leave files in their default locations, but if you use the script context to get the location from which the script is run you could find the shader preset in that folder or a sub-folder even if it had been moved.

    // Get the Content Manager
    var CMgr = App.getContentMgr();
    // If successful, load the targetFile
    if ( CMgr ) {
         success = CMgr.openFile( targetFile );
    }

    // Get the name of the current script to extract path
    var scriptName = getScriptFileName();
  • V3DigitimesV3Digitimes Posts: 3,123
    edited December 1969

    Thanks!

    For now all I'm trying to have a "all in one" fails.
    I tried to save as a deprecated material, and added at the end the script part to swap files, and the strange thing is that it behaves during the swapping as if the properties were the one of the old material not the new one.
    This means in practice that I have to apply the same script twice, and the first time it will apply the shader to the list of surfaces (but will not move the maps), the second time it will move the maps...

    So I've told to myself I was going to use the "openFile" you showed me here.
    But I cannot set it up yet, well, maybe because I'm just tired...

    I'm gonna sleep and try tomorrow morning with a fresh brain (scripting is very tiring!)
    Two questions remain :
    Can the "openFile( targetFile )" also open a duf file (and in this case will it be applied normally like a material preset)?
    what is the format of targetFile? A string? something else? must this contain the path too?

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    Yes, a string is the input with the full path - which is what I was suggesting using the script file name for. I do, somewhere, have a script that uses this so I will try tomorrow to dig it out and post the relevant snippet.

  • V3DigitimesV3Digitimes Posts: 3,123
    edited December 1969

    Thanks, your answer helped me a lot since I had less issues to investigate, and.....
    Finally I had it working!!!!!
    I based on a script I had made with your help (or Rob one?), which had been modified by Rob, to load an help pdf file from one of my product, and which I re-modified to open my duf with your help (again).
    For info :

    // DAZ Studio version 4.6.3.50 filetype DAZ Script// Greatly helped by a rbtwhiz (Rob) code initially used to open a pdf file in a ReadMe. Thank you Rob.// Greatly helped by Richard Haseltine, informations are in this thread : <a href="http://www.daz3d.com/forums/discussion/57229/#833568">http://www.daz3d.com/forums/discussion/57229/#833568</a>;// Additional Source Code used in this page can be found Here : <a href="http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/general_ui/display_document_dynamic/start">http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/general_ui/display_document_dynamic/start</a>;var oContentMgr = App.getContentMgr();var sRelativePath = "/Runtime/LoadMyMap2.duf";var sPreferredBasePath = oContentMgr.getMappedPath( getScriptFileName(), true, false );var sAbsolutePath = oContentMgr.getAbsolutePath( sRelativePath, true, sPreferredBasePath );if( !sAbsolutePath.isEmpty() ){ var b = String("%1").arg( sAbsolutePath ); success = oContentMgr.openFile&#40; b &#41;;

    the rest of the code displays an error message if the files where not found.

    I think this is really fine and I am going now to try to load the two scripts (first the shader, then the map mover) successively using this script, I hope this will work! I really love this solution, this is so flexible in term of development !
    I just hope the second file will see that the first file was applied...

    I really appreciate your help Richard, I'm not sure I would have dared going on with scripting without anybody supporting my effort when I'm lost !

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    You're welcome.

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited December 1969

    This is the sort of thing I had in mind (I couldn't find my existing example). If the presets are in a sub-folder of the script's folder, here called "Do not alter", then the function will work wherever the script and the folder are placed. You just need to pass the name of the sub-folder (in order to keep the code portable - you could add the sub-folder name as a string operation inside the function itself and just pass the bare name of the preset) after capturing the existing settings, then if the preset was applied successfully you run the code to apply the stored settings to the new shader.

    // Apply prset from script
    // (c) Richard Haseltine, June 2015
    
    function loadPreset( preset ) {
     // Get the name of this script file
     var scriptFile = getScriptFileName();
     // if it's an actual name, get a FileInfor object for it
     if ( scriptFile != "" ) {
      var fileInf = new DzFileInfo( scriptFile );
      // If we have a file info object use it to get the path,
      // then add the .duf file name ready to load
      if ( fileInf ) {
       // Get the path, without the file name
       var contentPath = fileInf.path();
       // If successful
       if ( contentPath != "" ) {
        // Add the location of the preset
        var dufFile = contentPath + preset;
        // Get the content manager
        var contMgr = App.getContentMgr();
        // if successful
        if ( contMgr ) {
         // Try to load the file and return success/failure
         return contMgr.openFile( dufFile );
        }
       }  
      }
     }
     // This will happen only if we failed at some stage
     return false;
    }
    
    // Code for gathering values goes here
    // Try to load the preset and apply saved values
    if ( loadPreset( "/Do not alter/blue.duf" ) ) {
     // Code for setting values goes here
    }
  • evilded777evilded777 Posts: 2,464

    V3Digitimes, did you ever get this working?

     

    I am looking to do, in sounds like, exactly the same thing you are: apply a material, look for certain maps and apply those maps in alternate channels.

    Its been so long since I scripted anything I am feeling totally lost.  I can understand a lot of the examples and things I am looking at... but, where to begin is a huge struggle.

  • mjc1016mjc1016 Posts: 15,001

    PM Mustakettu85, she has a 3Delight shader kit that has scripts to swap maps around; Bump to Displacement, etc.

     

  • evilded777evilded777 Posts: 2,464

    I may very well already have those scripts, mjc...I shall have to look at the package she gave me (i got distracted by iRay and haven't gone back to 3Delight since).

  • evilded777evilded777 Posts: 2,464

    And why the hell can't I get Richard's above script to work? Seems simple enough... I just need to tell it, somewhere, what the name of the actual duf file I want to apply is, right? And if its saved in the same location as the script I am running, it should apply it, right?

    I feel like such a noob! I'm not comfortable with that.

  • Richard HaseltineRichard Haseltine Posts: 100,457

    The script is set to load a file (blue.duf) from the folder Do not alter in the folder that contains the script. The .duf file can be anything, even a full scene, but if it's a preset you need to have the target item selected.

  • evilded777evilded777 Posts: 2,464

    Thank you, Richard, for pointing out the obvious, important part of the script that I was too dense to gather.

     

    You really gotta wonder where the hell my brain is at right now.

  • evilded777evilded777 Posts: 2,464

    You guys rock.

    I have most of the pieces now, I just gotta figure out how to make them all work together.

     

  • evilded777evilded777 Posts: 2,464

    Proper usage of isMapped()?

    I keep getting a parse error, so I am obviously doing something wrong.

     

    And are those code snippets above posted as an image?

  • mjc1016mjc1016 Posts: 15,001

    No, that looks like the code tags in the new forum software.

  • Richard HaseltineRichard Haseltine Posts: 100,457
    edited July 2015

    The code snippets are text, for me.

    Check that your property is a DzNumericProperty or a derivative, other properties don't have isMapped().

    if ( oProperty.inherits( "DzNumericProperty" ) {	bMapped = oProperty.isMapped();	// Do stuff}
    Post edited by Richard Haseltine on
  • evilded777evilded777 Posts: 2,464
    edited July 2015

    How do Generation 4 figures differ from Genesis in such a way that a script reading and setting material settings would not work the same?

     

    I'm basing my work on someone else's script, so... while I follow what its doing, I'm not sure its the best way to do it.

     

    using getobject, getcurrentshape and getnummaterials to iterate over the materials, then findproperty along with getMapValue to read a map then findproperty and setMap to apply it elsewhere.  Works great genesis 1 & 2... does absolutely nothing on Generation 4.

     

    also... what would be the appropriate method to use to set a value on a parameter like Bump Strength (iray uber shader)?

    Post edited by evilded777 on
  • evilded777evilded777 Posts: 2,464

    Apparently I was using an older version of the script that didn't work, so ignore the question about Gen 4 vs Genesis. Script works fine on both.

     

    Still looking to set that numeric value, though.

  • V3DigitimesV3Digitimes Posts: 3,123

    Hi evilded, sorry for the delay. After 3 weeks -or more- working on it, (I'm really not good at scripting), my script finally works "just enough" to do what I need. But there are plenty of things that I could not have work and that are finally by luck made by DS by simple variable name identification (regardless of the script). In order to set the numeric value it depends on the type of the value (the type of the property). Some will accept setmap, some won't, most of the time it remains a mystery to me, but I hope "when I'm tall I'll understand".

    In order to set map I use oProperty.setMap("the map") and in order to set the other properties I use for instance : g_oPresetHelper.setNumericPropertyWithAttributes( "name or label of the variable I don't rememeber", false, 0, 1, [ 1 ] );

    The g_oPresetHelper.setNumericPropertyWithAttributes is extracted from the dsa you have when you save for instance a material preset in dsa.

    I hope this helps..

  • evilded777evilded777 Posts: 2,464

    ok... making my way back in here, understanding better the script I am working from, etc.

    How do I grab the pieces of the Iray Uber material to understand what they are and what methods are available? There must be a way to do this.

  • Richard HaseltineRichard Haseltine Posts: 100,457

    What do you mean? Are you wanting parameters, or are you wanting shader networks or MDL code?

  • evilded777evilded777 Posts: 2,464

    Richard, looking for parameters and methods available for scripting, like what you see for DZDefaultMaterial in the old docs.

     

    ie

    Color getAmbientColor()

    DZColorProperty getAmbientColorControl()

     

    I saw there was an example script to get all the available properties, etc of a given node. http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/properties/node_properties/start

    I assume one can do the same thing for a material.

  • Richard HaseltineRichard Haseltine Posts: 100,457

    The general method is to use findProperty( "name" ) or findProeprtyByLabel( "label" ) on the material.The methods like getAmbientColor() are special utility functions that are tailored, for the most part, to the DAZ Default Shader. Then having got a property use inherits( "DzClassName" ) to make sure it is the right type for what you want to do.

  • evilded777evilded777 Posts: 2,464

    working, thinking, processing. I am not asking the correct question.

     

    I've manged to suss out the class name (DZUberIrayMaterial), but not much else.

    WTH does this tell me? And can I use it somehow to find out more information?

    TypeError: Result of expression 'myShineStrMap.setTopCoatBumpStrength' [undefined] is not a function

  • evilded777evilded777 Posts: 2,464

    "The DzAsset API is [thus far] undocumented, but can be explored [like any object] using a "for...in" loop to print member signatures."  -- rbt, from another post here, I don't know how to pont to particular posts yet.

    This is exactly what I want to do, only on the DZUberIUrayMaterial.  I understand the loop part, but what is a member signature and how do I tell it to print those?

  • evilded777evilded777 Posts: 2,464

    Took some creative Search Fu, but I found this...http://www.daz3d.com/forums/discussion/37769/

     

    Which may have lead me to what I need. Man, that's a lot of data to sift.

Sign In or Register to comment.