Krakatoa SR C++ API

Ok cool. I’m able to get the renderer generate some outputs within Eyeon Fusion now. But running into a few other issues, when the scene settings change.
Have another question:
Is the render() function supposed to return only when the rendering process is complete? Currently I read the output as soon as the render() call returns.
Many times my output renders are blank images and on the progress_callback ,I get just one call at 0% with no future calls. Whenever I see outputs, I see some
progress (around 50%). Should I wait till this callback indicates that the process is done (progress > 0.99 say), before I read the output file?
thanks

render() should definitely not return before the render is complete. Once render() returns, everything is complete.

For example, with the following code:

krakatoasr::krakatoa_renderer r;
//...
r.set_progress_logger_update( customProgressUpdate );
r.set_frame_buffer_update( customFrameBufferUpdate );
r.set_render_save_callback( customRenderSaver );
//...
r.render();

STEP 1 in r.render() (during processing):

  • There will be one or more calls to your customProgressUpdate->set_title() and customProgressUpdate->set_progress()
  • There will be zero or more calls to your customFrameBufferUpdate ->set_frame_buffer()

STEP 2 in r.render() (finishing step):

  • One final call to your customFrameBufferUpdate->set_frame_buffer().
  • Lastly, a single call to your customRenderSaver->save_render_data().

Then r.render() returns.

Are you getting your final data using your render saver’s save_render_data() function? That’s where all the final images are processed.

The standard way of doing it is like so:

krakatoasr::krakatoa_renderer r;
//...
krakatoasr::file_saver fileSaver( "my_output_image.tiff" );
r.set_render_save_callback( &fileSaver );
//...
r.render();

Thanks Conrad.
I’m using the default file_saver class. It’s not that I don’t ever get any output, but just that sometimes the output is blank sometimes. It should be some error in my settings. I’ll try to figure this out.

Do you have a case I could try that always reproduces the problem?

I can reproduce the problem, but my current setup needs Eyeon Fusion for reproduction. However I think I have an idea what the issue is. There were two issues

  1. The matrix transform APIs(eg set_camera_tm) were taking inputs in column-major orders and I was passing them in row-major (which I think is how the python API consumes it). I’ve fixed this issue already.
  2. The second I think has something to do with the particle_stream. My current version creates a new instance of krakatoa_renderer every time the scene changes, just for sanity. My code does something like this:
class PRTData{
    private:
    particle_stream_interface *psptr;
public:
    particle_stream pstream;
    PRTData(){
       psptr = new my_stream(100);//This is the same sample code uploaded.
       pstream = particle_stream::create_from_particle_stream_interface(psptr);
    }
};

class UITool{
    public:
    PRTData* prtdata;
    void handleUI(){ //Handles any event from user.
        prtdata = new PRTData();
    }
};

class Renderer{
    
    krakatoa_renderer kr;
    void Render(PRTData* prtdata){ //Passed in from the UI Tool.
        krakatoa_renderer kr_local;
        particle_stream pstream = prtdata->pstream;
        kr_local.add_particle_stream(stream);
        //set up other stuff - camera, lights, saver etc
        kr_local.render();
        //retrieve saved image.
        outputimage = read_saved_image();
    }
};

In this example above, the new particle stream is only created when there’s a user event. If the camera just changes, the stream is not created.
But a new kr_local object is created each time and it uses the same pstream. When this starts i get images correctly, but say if I rotate the camera so that it doesn’t focus on the particles anymore I get a blank image(which is expected). But when I rotate it back to the correct position again the output continues to be black. From this point I can’t to anything to the camera to get any output. I have to restart the app.
But if I trigger a user event, so that the pstream gets regenerated (from the constructor of PRTData), the particles come back. So this may have something to do with what happens to the stream after the render is done (maybe it gets freed/reassigned somehow?).
Let me know if this is not clear. Also my email address is aramasamy@thevisualmd.com if you want to continue this discussion outside the forum.
Thanks

HI Conrad,

Still having trouble with reusing particle streams once it has been rendered once. Do you have an example for that can do this. Basically I want to either
Create a particle_stream_interface object just once and reuse it with multiple instances of the krakatoa_renderer that gets created, for each render:

a. Create[i] particle_stream_interface [/i](psi)
b. Create[i] krakatoa_renderer[/i](kr).
c. Create [i]particle_stream[/i] from psi.
d. Add[i] particle_stream[/i] to kr. 
e. Render. 
f. Remove all [i]particle_stream[/i] objects from kr.
g. Apply any changes to scene ( say camera transform)
h. Loop back to [b]step b[/b]. for next render. (Note: the psi object is reused.)

OR.
Create a single krakatoa_renderer object and reset the particle_stream (remove and add new) only when it changes:

Steps:
a. Create[i] particle_stream_interface [/i](psi)
b. Create[i] krakatoa_renderer[/i](kr).
c. Create [i]particle_stream[/i] from psi.
d. Add[i] particle_stream[/i] to kr. 
e. Render. 
f. Apply any changes to scene ( say camera transform)
g. Loop back to [b]step e [/b]. for next render. (Note: All the objects are created just once and reused in the next render)

Either option is fine as long as the render is successful. Currently I get blank images for both versions, unless I forcefully recreate the particle_stream_interface object(psi) for each render call, in which case I get a successful render.
Thanks arun

Just wanted to update that the issue of disappearing output is resolved. The problem was that after each render I wasn’t resetting my particle_stream_interface. I’ve added a callback from my renderer code that will reset the particle generator. Maybe this is something that can be added to the API like:

    class ParticleStream : public krakatoasr::particle_stream_interface{
        int mycounter;
        public:
            void Reset(){ mycounter = 0;}
    }
    //somewhere else inside the renderer the callback is called similar to how a saver is called.
    void render(){ //fictional renderer code
        ...
        saver.save(framebuffer);//etc...
        foreach(stream in streams){    stream.Reset();    }
    }

This way each stream will know when the rendering is done. Currently there’s no way to know this and the user has to implement a callback system.

As an aside, I’ve a question about saving .PRT files as output from the renderer. The python documentation says that this feature is supported. When I attempted it using the C++ API, I get an error saying:

.
Other image output formats work fine. Is this a feature yet to be added into the C++ API.

thanks

PRT is the particle format, not an image format. Isn’t it?

For the “reusing streams” question. What you are seeing is actually the expected behavior. The stream object is “exhausted” once all the particles are gone from it. The concept of a stream is that it’s feed particle by particle and once it reaches the end, the stream is useless. It is done this way to avoid having particles in memory twice (all particles need to held and sorted internally during render). I understand how this behavior can be confusing.

This can be a little tricky, and I understand why you might want to keep particles in memory between renders. There are two ways of dealing with this:

  1. Create a stream that can read a chunk of memory over and over again.
    -This would involve saving all your particles in-memory, and creating a custom particle stream.
    -The stream would just be an iterator object that would read over the existing memory. You would create a new iterator stream each render.

  2. I am planning to implement an “in-memory cache” in Krakatoa. Basically what this means is that before you render you flag your renderer as “CACHING”, then the particles themselves are held by the krakatoa_renderer object, and in the next render, if you request it, it will reuse that cache. To use this option, you would have to stop recreating the krakatoa_renderer object between renders. Is this something that would be valuable to you?

I would be hesitant to add a “reset” function to the stream. As in some cases, streams cannot be reset.

As for the “set_render_save_callback” callback question, that is for saving image output (RGBA, etc). The output file_saver takes a filename and determines the image type based on the extension.

If you with to save out the renderer’s particles as a PRT file, you will have to use a different function. Currently the API doesn’t have this, but I’ll be sure to put it in there asap, as the Python renderer is doing it, so we should also make sure it’s exposed to the API. Thanks for the suggestion.

I do have something that does this essentially. The problem is that I ended up reusing the iterator (without recreating it or resetting it to begin), because there’s no indication as to when the current render ended and the next render began. Of course, the next render is triggered on a user action, but what if the user just changed the camera position. Then my PRT source tool doesn’t get any notification to regenerate/reset the iterator, which was the essence of the problem.

Yes. But it is not a priority, at least for us, since we’ve gotten around this issue.We’re more interested in the following features

  1. Saving .PRT files as outputs
  2. Creating Light/Particle cache outputs
  3. The “pointsVolume” option, supported in python, but which is not available in C++ ( am I right?)

Another discrepancy I noticed is that the python API takes FOV arguments in degrees, while the C++ API requires radians. Not an important issue, but it might confuse someone who’s using both your python and C++ APIs.

Excellent. Thank you for your feedback. It would be nice to have the actual renderer cache the particles. That way you would only have to have the particles in memory once. If you cache them outside the renderer, then it would have to have the particles in memory twice at some times (which I would like to avoid).

I’m not quite sure what you mean by “Creating Light/Particle cache outputs”. But the other two are on the list of features we’ll be supporting.

If we cache the particles outside the render, then yes, we have 2x memory usage, but we can then move the camera without having to reprocess the particles (other than just handing it off to Krakatoa again).

Multiple cache levels has been on the Krakatoa MX wishlist for a while because of this. We want several layers so that every time you move the camera you aren’t pulling 20GB of data off of the network. :slight_smile:

By “Creating Light/Particle cache outputs” I mean the PCache/LCache maintained by the renderer - thinkboxsoftware.com/krak-particle-cache/. In Krakatoa MX, the user can enable these caches inside the renderer for any future render calls as an option. This is something we’re very interested in.
If this is something you’re planning to support as a part of the “in-memory cache” you described earlier, then my request is mute :slight_smile:

Ah, I see what you mean by Particle/light cache. Ideally I would like to match the Krakatoa MX functionality in this regard, yes.

I just tried to load the library from the last build from 1. August.
Unfortunatly my plugin will not load in maya. It seems that the problem is caused by a missing library.

In the dependency walker I can see that two libraries are unknown in the current build:

MSVCP990.dll
and
MSVCR90.dll

I compared with an old krakatoaSR.dll and there the librarays are listed as well but they do not have a questionmark in the dependency walker and are marked with a small 64. So the old libraries are found, the new ones not.

Do you have any idea what’s wrong with my project? I’m using MS Visual Studio 2010.

I have no idea what might have caused dependency changes. I’ll take a look here and see what I can track down what this might be. Can you export and send me the output from Dependency Walker? I’d like to take a look at what your computer is saying compared to mine.

Strange thing… just tested the same library with my machine at home and here everything works fine. So I suspect my machine at work has a problem. I’ll report any solution if I find one.

Unfortunatly no success yet. I have no idea what’s the problem. To test it, I created a simple program which uses the krakatoaSR.dll. It does nothing, only prints a string and waits for a character input.

Then I compiled it using an old version of the KrakatoaSR and one with the new version. The old one runs, the new one not.
I’ve attached the text output of the dependency walker of the old and the new dll in the attached depends.zip.

In the attached libProbleme.zip I have collected the visual studio project as well as the debug and release output. Simply clicking on the srtest.exe results in a missing lib message (you should put the tbb libs into the appropriate dirs or set the path) in the tools compiled with the new version. The old version simply works. The old is compiled with the version 2.1.2.47644 from July.

If you could have a look at the files, it would be great. I have no ideas any more.
depends.zip (20.1 KB)

I tried the KrakatoaSR.dll from 08/01 and am running into the same issue as haggi.Windows ends up unloading my dll (which in turn uses the KrakatoaSR.dll). Once I restore to the old one, all is good.
In my dep. walker I saw that the old one had a dependancy on tbbmalloc.dll, which is missing in the new one. But it is able to find MSVCR90 and MSVCP90 for the new one and displays x64 correctly. Let me know if you need any other info.