IPC Between Daz Script and Mono.net Console App

simtenerosimtenero Posts: 383

Hello All,

I was wondering if there was a decent IPC solution that could be used with a Daz Script.  I'm currently writing geometry to files and then parsing those inside a Mono console app, but it's a pretty slow way of consuming a large amount of data.  Mono doesn't support named pipes, which would be ideal, but I'm wondering if there's a simpler solution I'm overlooking.

I've considered building a socket server into the console app and sending data as network requests, but I need to be able to send a response back to Daz.  I'm not great with C++, so I'm hoping to figure this out with scripts, though I concede that may not be possible.

Edit: I should point out I've experimented with Standard Input and Output, but I've run into a lot of sync issues.  I'm not sure if it's the way Mono writes to StdOut, but events aren't being reliably triggered and I end up with incomplete strings back in Daz.  If this is the only solution, I'm open to making it work, but hoping for something else.

Thoughts?

Post edited by simtenero on

Comments

  • djigneodjigneo Posts: 283
    edited November 2015

    Pretty sure you want to consume the DzProcess class. Check http://www.daz3d.com/forums/discussion/comment/833324 for a discussion and example as to how to get that working.

    I've done it successfully consuming a command line app, so I should be able to assist somewhat if you get stuck.

    Post edited by djigneo on
  • simtenerosimtenero Posts: 383
    edited November 2015

    Thanks for the response, djigneo!  Agreed, that looks like the best bet.  Did you use Standard in/out to pass data?  At a glance, something like this?:

    var process = new DzProcess(appPath);

    process.canReadLineStdout (true);

    connect( process, "readyReadStdout()", stdOut);

    process.start();

    while (process.running)

    {

    //Wait Around

    }

    function stdOut()

    {

    print(process.readStdout());

    }

    Edited: Also, does this method allow for writing back to Standard Input, or are the command arguments the only way to pass data to the console app?

    Post edited by simtenero on
  • djigneodjigneo Posts: 283
    edited November 2015

    From a glance at the DzProcess object, it didn't seem like there was an obvious way to pass information other than via DzProcess.arguments.

    var oProcess = new DzProcess();for (var prop in oProcess)	print(prop);

    My code populates DzProcess.arguments, but maybe try a few things out based on what you can see from the above code snippet. There does appear to be some StdIn things, but I'm unclear how to use them. Maybe an expert will poke in and help us out there.

    I ended up with something like this for the actual process execution. The processEvents() call is pretty important, as is waiting for the process to complete (so the script doesn't terminate prematurely).

    var oTimer = new DzTimer();oTimer.singleShot = true;oTimer.start(nTimeout); 	if (oProcess.start()) {	print("process started...");			}else {	print("process failed to start!");}while (oProcess.running && (oTimer.active == true)) {	processEvents(); }if (oTimer.active == false) {	print("Process timed out!");	oProcess.tryTerminate();}

     

    Post edited by djigneo on
  • Thanks for the example, very helpful :-D  There is a "writeToStdin" method, but I haven't had much luck with it.  I'll keep tinkering, but it looks like this is going to be the best bet (though I may keep poking around for alternatives, just in case :-)).

  • djigneodjigneo Posts: 283

    I would recommend getting the basics working by passing arguments in. It took me a lot of fiddling to get it to work at all, so I would get proof of life before crossing any avenues off the list. Some of the things that should be really easy in DAZ Script take me a very long time to get right.

  • Quick update:  Just had a small success!  process.writeToStdin("Hello Console App") writes characters to StDout, but not lines.  Adding a carriage return, process.writeToStdin("Hello Console App \n") registers the entry as a line, which the console app can read with Console.ReadLine()!

    That seems like it might resolve the sync issues I mentioned (where I would get only portions of a string).  Also, thank you again for the example, the timer was critical.  I didn't realize that, by default, Daz Script terminates the app once the event queue is cleared.  Adding the timer gave the console app enough time to do it's thing.  Woot! :-)

  • djigneodjigneo Posts: 283

    Sweet! Good to hear you got it working. What's your project doing, if you don't mind sharing?

  • Nope, I don't mind :-D  I've got a home-grown softbody physics engine I've been working on for a while.  I've been on the lookout for a good platform to integrate it with.  Starting with Daz.  If it goes well, I may attempt a Blender integration as well (it's different enough from Blender's existing physics sims to maybe justify the effort).  I've got it working at the moment using file inputs/outputs, but it requires geometry information for every phsyics step.  It takes longer to write and read those files than to run the actual simulation! :-P  That's why the ICP is so critical.  If I can't make it work via script, I'll have to come up with a server/client setup with the Daz SDK, which would take loads more time than I have to invest at the moment.

  • Hi simtenero. Did you finally make it work? If so could you share the communication code for .net and daz? 

    Thanks!

  • simtenerosimtenero Posts: 383
    edited February 2016

    Hey Flashmoyo, I'm sorry I didn't see this sooner, hopefully this is still of some use to you :-)

    On the Daz side, it looks like:

     

    var inputString;var process = new DzProcess(appPath);var nTimeout = 10000;var timer = new DzTimer();timer.singleShot = true;timer.start(nTimeout);process.communication = process.Stdin | process.Stdout | process.Stderr;process.canReadLineStdout (true);connect( process, "readyReadStdout()", stdOut);connect( process, "readyReadStderr()", stdErr);process.start();while (process.running && (timer.active == true)){	processEvents();}function stdOut(){	inputString = process.readStdout();}function stdErr(){	inputString = process.readStderr();	print(inputString);}

     

    And in a .Net console app, something like this:

     

    using System;using System.IO;namespace STDOut{	class MainClass	{		public static void Main (string[] args)		{			StreamReader sin = new StreamReader(Console.OpenStandardInput());			StreamWriter sout = new StreamWriter (Console.OpenStandardOutput ());			Console.WriteLine ("Hello Daz Script.");  //read by Daz Script			string s;			while ((s = Console.ReadLine()) != null)			{				//"s" is recieved from Daz Script			}		}	}}

     

    You have to be careful of the length of your strings.  Line breaks from Daz won't translate as line breaks in .Net, so you need to create some custom notation to check that you are done recieving a line before your request the next line from the script.   If you don't, the console app or script can get ahead of itself and try to read a line that isn't there yet.

     

    Hope that helps!

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